diff --git a/.fz/calculators/Model.sh b/.fz/calculators/Model.sh index 02fa528..5c94e3f 100755 --- a/.fz/calculators/Model.sh +++ b/.fz/calculators/Model.sh @@ -28,19 +28,27 @@ fi PID_FILE=$PWD/PID echo $$ >> $PID_FILE -# Mock calculation: extract the value from the input file and write to output +# Mock calculation: extract values from the input file and compute a result # This simulates a real calculation that produces an output file # Replace this section with actual calls to your simulation code echo "Running mock calculation on $input..." -# Extract variable value from input (looking for "value = X" pattern) -value=$(grep -E '^value\s*=' "$input" | sed 's/.*=\s*//' | tr -d '[:space:]') +# Extract variable values from input (looking for "var = X" pattern) +x=$(grep -E '^x\s*=' "$input" | sed 's/.*=\s*//' | tr -d '[:space:]') +y=$(grep -E '^y\s*=' "$input" | sed 's/.*=\s*//' | tr -d '[:space:]') +z=$(grep -E '^z\s*=' "$input" | sed 's/.*=\s*//' | tr -d '[:space:]') -if [ -n "$value" ]; then - # Mock computation: just return the value (or compute something from it) - result=$value - echo "Input value: $value" +# Fallback to 'value' for backwards compatibility +if [ -z "$x" ]; then + x=$(grep -E '^value\s*=' "$input" | sed 's/.*=\s*//' | tr -d '[:space:]') +fi + +if [ -n "$x" ]; then + # Mock computation: compute result = x + y + z (or just x if y,z not present) + # Using awk with -v for safe variable passing + result=$(awk -v x="${x:-0}" -v y="${y:-0}" -v z="${z:-0}" 'BEGIN { print (x+0) + (y+0) + (z+0) }') + echo "Input values: x=$x, y=${y:-0}, z=${z:-0}" echo "Result: $result" echo "$result" > output.txt echo "Calculation completed successfully." diff --git a/README.md b/README.md index 2d25061..bea39c7 100644 --- a/README.md +++ b/README.md @@ -31,18 +31,20 @@ pip install git+https://github.com/Funz/fz.git ```python import fz -# Example: Run calculation with varying x value +# Example: Run calculation with varying parameters results = fz.fzr( input_path="examples/Model/input.txt", input_variables={ - "x": [1.0, 2.0, 3.0, 4.0, 5.0] + "x": [1.0, 2.0, 3.0, 4.0, 5.0], + "y": [1.0, 2.0], + "z": [0.5] }, model="Model", calculators="localhost_Model", results_dir="my_results" ) -print(results[['x', 'result']]) +print(results[['x', 'y', 'z', 'result']]) ``` ### Directory Structure @@ -69,11 +71,14 @@ your_project/ # Example input file for Model plugin # Variables are defined using ${variable_name} syntax -value = ${x} +# Input parameters +x = ${x} +y = ${y} +z = ${z} ``` In this example: -- `${x}` is a variable parameter that will be substituted by fz +- `${x}`, `${y}`, and `${z}` are variable parameters that will be substituted by fz - Lines starting with `#` are comments ## Creating Your Own Plugin diff --git a/example_usage.ipynb b/example_usage.ipynb new file mode 100644 index 0000000..9515117 --- /dev/null +++ b/example_usage.ipynb @@ -0,0 +1,322 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# fz-Model Plugin Example Usage\n", + "\n", + "This notebook demonstrates how to use the fz-Model plugin template.\n", + "\n", + "The examples cover:\n", + "1. Installing dependencies (fz framework and fz-Model plugin)\n", + "2. Downloading example input files\n", + "3. Parsing input files to identify variables\n", + "4. Compiling input files with specific parameter values\n", + "5. Running calculations with the mock calculator\n", + "6. Performing parametric studies\n", + "\n", + "**Note:** This is a template plugin with a mock calculator. Replace the calculator script with calls to your actual simulation code." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Setup: Install Dependencies\n", + "\n", + "First, install the Funz framework and the fz-Model plugin." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Install fz framework from GitHub\n", + "%pip install -q git+https://github.com/Funz/fz.git\n", + "\n", + "# Install fz-Model plugin\n", + "import fz\n", + "fz.install(\"Model\")\n", + "\n", + "print(\"✓ Dependencies installed successfully!\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Setup: Download Example Files\n", + "\n", + "Download the example input files from the GitHub repository." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import os\n", + "import urllib.request\n", + "\n", + "# Create directory for examples\n", + "os.makedirs(\"Model\", exist_ok=True)\n", + "\n", + "# Base URL for raw GitHub content\n", + "base_url = \"https://raw.githubusercontent.com/Funz/fz-Model/main/examples\"\n", + "\n", + "# Download example files\n", + "files_to_download = [\n", + " (\"Model/input.txt\", f\"{base_url}/Model/input.txt\"),\n", + "]\n", + "\n", + "print(\"Downloading example files...\")\n", + "for local_path, url in files_to_download:\n", + " try:\n", + " urllib.request.urlretrieve(url, local_path)\n", + " print(f\" ✓ Downloaded: {local_path}\")\n", + " except Exception as e:\n", + " print(f\" ✗ Failed to download {local_path}: {e}\")\n", + "\n", + "print(\"\\n✓ Example files ready!\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Import Required Libraries" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import fz\n", + "import os\n", + "import tempfile\n", + "\n", + "print(f\"fz version: {fz.__version__ if hasattr(fz, '__version__') else 'unknown'}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Example 1: Parse Input File for Variables\n", + "\n", + "Use `fz.fzi()` to identify variables in an input file." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Parse the input file to find variables\n", + "variables = fz.fzi(\n", + " \"Model/input.txt\",\n", + " \"Model\"\n", + ")\n", + "\n", + "print(f\"Variables found in input.txt: {list(variables.keys())}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Example 2: Compile Input Files\n", + "\n", + "Use `fz.fzc()` to compile input files with specific parameter values. This substitutes variables with actual values." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Create temporary directory for compiled files\n", + "with tempfile.TemporaryDirectory() as tmpdir:\n", + " # Compile input with specific values\n", + " fz.fzc(\n", + " \"Model/input.txt\",\n", + " {\"x\": 3.14, \"y\": 2.0, \"z\": 1.5},\n", + " \"Model\",\n", + " output_dir=tmpdir\n", + " )\n", + " \n", + " # Show compiled file\n", + " # Find the compiled file (it may be in a subdirectory)\n", + " for root, dirs, files in os.walk(tmpdir):\n", + " for f in files:\n", + " if f == \"input.txt\":\n", + " compiled_file = os.path.join(root, f)\n", + " print(f\"Compiled file content (x=3.14, y=2.0, z=1.5):\")\n", + " print(\"=\" * 70)\n", + " with open(compiled_file, 'r') as file:\n", + " print(file.read())" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Example 3: Run a Basic Calculation\n", + "\n", + "Run a simple calculation using the mock calculator.\n", + "\n", + "**Note:** This uses the template's mock calculator which simply returns the input value. Replace the calculator script with your actual simulation code for real calculations." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Define parameter values\n", + "input_variables = {\n", + " \"x\": [1.0, 2.0, 3.0, 4.0, 5.0]\n", + "}\n", + "\n", + "try:\n", + " # Run parametric calculation\n", + " results = fz.fzr(\n", + " input_path=\"Model/input.txt\",\n", + " input_variables=input_variables,\n", + " model=\"Model\",\n", + " calculators=\"localhost_Model\",\n", + " results_dir=\"results/basic_study\"\n", + " )\n", + " \n", + " # Display results\n", + " print(\"\\nResults:\")\n", + " print(\"=\" * 70)\n", + " print(results[['x', 'result', 'status']])\n", + " \n", + "except Exception as e:\n", + " print(f\"\\nError running calculation: {e}\")\n", + " print(\"Note: Make sure the calculator script is properly configured.\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Example 4: Multi-Parameter Study\n", + "\n", + "Demonstrate a parametric study with multiple variables." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "\n", + "# Define multiple parameters\n", + "input_variables = {\n", + " \"x\": np.linspace(1.0, 5.0, 5).tolist(),\n", + " \"y\": [1.0, 2.0],\n", + " \"z\": [0.5]\n", + "}\n", + "\n", + "print(f\"Running parametric study...\")\n", + "print(f\" x values: {input_variables['x']}\")\n", + "print(f\" y values: {input_variables['y']}\")\n", + "print(f\" z values: {input_variables['z']}\")\n", + "\n", + "try:\n", + " # Run parametric calculation\n", + " results = fz.fzr(\n", + " input_path=\"Model/input.txt\",\n", + " input_variables=input_variables,\n", + " model=\"Model\",\n", + " calculators=\"localhost_Model\",\n", + " results_dir=\"results/multi_param_study\"\n", + " )\n", + " \n", + " # Display results\n", + " print(\"\\nResults:\")\n", + " print(\"=\" * 70)\n", + " print(results)\n", + " \n", + "except Exception as e:\n", + " print(f\"\\nError running parametric study: {e}\")\n", + " print(\"Note: Make sure the calculator script is properly configured.\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Example 5: Visualization\n", + "\n", + "If you have results, you can visualize them using matplotlib." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import matplotlib.pyplot as plt\n", + "\n", + "# Example visualization (using mock data if real results aren't available)\n", + "try:\n", + " # Use actual results if available\n", + " if 'results' in dir() and results is not None:\n", + " x_values = results['x'].values\n", + " result_values = results['result'].values\n", + " else:\n", + " # Use mock data for demonstration\n", + " x_values = [1.0, 2.0, 3.0, 4.0, 5.0]\n", + " result_values = [1.0, 2.0, 3.0, 4.0, 5.0] # Mock: result = x\n", + " \n", + " plt.figure(figsize=(10, 6))\n", + " plt.plot(x_values, result_values, 'o-', linewidth=2, markersize=8)\n", + " plt.xlabel('x', fontsize=12)\n", + " plt.ylabel('result', fontsize=12)\n", + " plt.title('Parametric Study Results', fontsize=14, fontweight='bold')\n", + " plt.grid(True, alpha=0.3)\n", + " plt.tight_layout()\n", + " plt.show()\n", + " \n", + "except Exception as e:\n", + " print(f\"Visualization error: {e}\")" + ] + } + ], + "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.10.0" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/examples/Model/input.txt b/examples/Model/input.txt index aa74b94..8cc1eaf 100644 --- a/examples/Model/input.txt +++ b/examples/Model/input.txt @@ -1,4 +1,7 @@ # Example input file for Model plugin # Variables are defined using ${variable_name} syntax -value = ${x} +# Input parameters +x = ${x} +y = ${y} +z = ${z} diff --git a/tests/test_plugin.py b/tests/test_plugin.py index 712a894..0594cfe 100644 --- a/tests/test_plugin.py +++ b/tests/test_plugin.py @@ -125,6 +125,8 @@ def test_with_fz(): print(" Testing fz.fzi() on input.txt...", end=" ") variables = fz.fzi("examples/Model/input.txt", "Model") assert "x" in variables, "Variable 'x' not found in parsed input" + assert "y" in variables, "Variable 'y' not found in parsed input" + assert "z" in variables, "Variable 'z' not found in parsed input" print("✓") # Test compiling input file @@ -132,20 +134,28 @@ def test_with_fz(): with tempfile.TemporaryDirectory() as tmpdir: fz.fzc( "examples/Model/input.txt", - {"x": 3.14}, + {"x": 3.14, "y": 2.71, "z": 1.5}, "Model", output_dir=tmpdir ) - # Check compiled file exists - compiled_file = os.path.join(tmpdir, "x=3.14", "input.txt") - assert os.path.exists(compiled_file), "Compiled file not created" + # Check compiled file exists (it may be in a subdirectory) + compiled_file = None + for root, dirs, files in os.walk(tmpdir): + if "input.txt" in files: + compiled_file = os.path.join(root, "input.txt") + break + assert compiled_file is not None, "Compiled file not created" - # Check variable was substituted + # Check variables were substituted with open(compiled_file, 'r') as f: content = f.read() - assert "3.14" in content, "Variable not substituted" - assert "${x}" not in content, "Variable marker still present" + assert "3.14" in content, "Variable x not substituted" + assert "2.71" in content, "Variable y not substituted" + assert "1.5" in content, "Variable z not substituted" + assert "${x}" not in content, "Variable marker ${x} still present" + assert "${y}" not in content, "Variable marker ${y} still present" + assert "${z}" not in content, "Variable marker ${z} still present" print("✓") print(" fz integration tests passed!\n")