From 6ec568ab0c557ecbdc69739e68a502806453bc53 Mon Sep 17 00:00:00 2001 From: Tyler Martin Date: Tue, 4 Mar 2025 19:45:01 -0500 Subject: [PATCH 1/8] [feat] adds reading/writing Pipelines to json - New _stored_args hidden attribute gathers the passed arguments at runtime - Modifications to this argument dictionary are transparent to the user and happen automatically - _stored_args used to create json reprsentations of PipelineOps and json serialization trivially created by iterating Pipeline - print_code also updated to use _stored_args --- AFL/double_agent/Pipeline.py | 78 +++++++++++++++++------ AFL/double_agent/PipelineOp.py | 110 ++++++++++++++++++++++++++++++--- 2 files changed, 161 insertions(+), 27 deletions(-) diff --git a/AFL/double_agent/Pipeline.py b/AFL/double_agent/Pipeline.py index 2ee273e..7d5eaaf 100644 --- a/AFL/double_agent/Pipeline.py +++ b/AFL/double_agent/Pipeline.py @@ -18,6 +18,9 @@ import re from typing import Generator, Optional, List import warnings +import datetime +import json +import pathlib import matplotlib.pyplot as plt import networkx as nx @@ -29,7 +32,6 @@ from AFL.double_agent.PipelineContext import PipelineContext from AFL.double_agent.PipelineOp import PipelineOp from AFL.double_agent.util import listify -from AFL.double_agent.util import extract_parameters class Pipeline(PipelineContext): @@ -120,29 +122,18 @@ def print(self) -> None: def print_code(self) -> None: """String representation of approximate code to generate this pipeline - Run this method to produce a string of Python code that should **approximate** - this Pipeline. If all constructor parameters are not stored as class attributes, - this method will fail and the code result will need to be edited. - - Warning - -------- - This method is approximate. The code generated by this method may not produce - an identical Pipeline to this method. Use with caution. + Run this method to produce a string of Python code that should + recreate this Pipeline. """ - warnings.warn( - """Pipeline.emit_code() cannot perfectly infer pipeline code and is not""" - """ guaranteed to reproduce the same pipeline. Use with caution.""", - stacklevel=2, - ) output_string = f"with Pipeline(name = \"{self.name}\") as p:\n" for op in self: - params = extract_parameters(op) + args = op._stored_args output_string += f" {type(op).__name__}(\n" - for k, v in params.items(): + for k, v in args.items(): if isinstance(v, str): output_string += f' {k}="{v}",\n' else: @@ -168,10 +159,57 @@ def clear_outputs(self): def copy(self) -> Self: return copy.deepcopy(self) + + def write_json(self,filename:str,overwrite=False): + """Write pipeline to disk as a JSON + + Parameters + ---------- + filename: str + Filename or filepath to be written + """ + + if not overwrite and pathlib.Path(filename).exists(): + raise FileExistsError() + + pipeline_dict = { + 'name':self.name, + 'date': datetime.datetime.now().strftime('%m/%d/%y %H:%M:%S-%f'), + 'ops':[op.to_json() for op in self] + } + + with open(filename,'w') as f: + json.dump(pipeline_dict,f,indent=1) + + @staticmethod + def read_json(filename: str): + """Read pipeline from json file on disk - def write(self, filename: str): + Usage + ----- + ```python + from AFL.double_agent.Pipeline import Pipeline + pipeline1 = Pipeline.read_json('pickled_pipeline.pkl') + ```` + """ + with open(filename, "r") as f: + pipeline_dict = json.load(f) + + pipeline = Pipeline( + name=pipeline_dict['name'], + ops=[PipelineOp.from_json(op) for op in pipeline_dict['ops']] + ) + + return pipeline + + + def write_pkl(self, filename: str): """Write pipeline to disk as a pkl + .. warning:: + Please use the read_json and write_json methods. The pickle methods + are insecure and prone to errors. + Parameters ---------- filename: str @@ -184,9 +222,13 @@ def write(self, filename: str): pickle.dump(pipeline, f) @staticmethod - def read(filename: str): + def read_pkl(filename: str): """Read pipeline from pickle file on disk + .. warning:: + Please use the `read_json` and `write_json` methods. The pickle methods + are insecure and prone to errors. + Usage ----- ```python diff --git a/AFL/double_agent/PipelineOp.py b/AFL/double_agent/PipelineOp.py index 4a2fbe5..d63f9df 100644 --- a/AFL/double_agent/PipelineOp.py +++ b/AFL/double_agent/PipelineOp.py @@ -2,6 +2,9 @@ import warnings from abc import ABC, abstractmethod from typing import Optional, Dict, List +import inspect +import json +import importlib import matplotlib.pyplot as plt import xarray as xr @@ -39,19 +42,18 @@ def __init__(self, 'No input/output information set for PipelineOp...this is likely an error', stacklevel=2 ) - - if name is None: - self.name = 'PipelineOp' - else: - self.name = name - + + self.name = name or 'PipelineOp' self.input_variable = input_variable self.output_variable = output_variable self.input_prefix = input_prefix self.output_prefix = output_prefix - self.output: Dict[str, xr.DataArray] = {} + # variables to exclude when constructing attrs dict for xarray + self._banned_from_attrs = ['output', '_banned_from_attrs'] + + ## PipelineContext try: # try to add this object to current pipeline on context stack PipelineContext.get_context().append(self) @@ -59,8 +61,98 @@ def __init__(self, # silently continue for those working outside a context manager pass - # variables to exclude when constructing attrs dict for xarray - self._banned_from_attrs = ['output', '_banned_from_attrs'] + ## Gathering Arguments of Most-derived Child Class + + # Retrieve the full stack. + stack = inspect.stack() + valid_frames = [] + # Iterate through all frames in the stack. + for frame_info in stack: + # Look for __init__ functions where 'self' is our instance. + if frame_info.function == '__init__' and frame_info.frame.f_locals.get('self') is self: + valid_frames.append(frame_info) + if valid_frames: + # Choose the last __init__ call in the inheritance chain. + final_frame = valid_frames[-1].frame + args_info = inspect.getargvalues(final_frame) + else: + # Fallback: use the immediate caller if nothing was found. + final_frame = inspect.currentframe().f_back + args_info = inspect.getargvalues(final_frame) + + # Build _stored_args by checking JSON serializability of each constructor argument. + stored_args = {} + for arg in args_info.args: + if arg != "self": + value = args_info.locals[arg] + try: + json.dumps(value) + except (TypeError, OverflowError) as e: + raise TypeError( + f"Constructor argument '{arg}' with value {value!r} of type {type(value).__name__} " + f"is not JSON serializable: {e}" + ) + stored_args[arg] = value + self._stored_args = stored_args + + def __getattribute__(self, name): + # Avoid recursion when accessing _stored_args. + if name == '_stored_args': + return object.__getattribute__(self, name) + + stored_args = object.__getattribute__(self, "_stored_args") + if name in stored_args: + return stored_args[name] + return object.__getattribute__(self, name) + + def __setattr__(self, name, value): + if name == "_stored_args": + return object.__setattr__(self, name, value) + + try: + stored_args = object.__getattribute__(self, "_stored_args") + except AttributeError: + stored_args = None + + if stored_args is not None and name in stored_args: + try: + json.dumps(value) + except (TypeError, OverflowError) as e: + raise TypeError( + f"New value for attribute '{name}' with value {value!r} of type {type(value).__name__} " + f"is not JSON serializable: {e}" + ) + stored_args[name] = value + else: + object.__setattr__(self, name, value) + + def to_json(self): + """ + Serializes the fully qualified class name and the constructor arguments + stored in _stored_args into a JSON string. + """ + cls = self.__class__ + module = cls.__module__ + qualname = cls.__qualname__ + data = { + "class": f"{module}.{qualname}", + "args": self._stored_args + } + return data + + @classmethod + def from_json(cls, json_data): + """ + Deserializes the JSON string back to an object. + Dynamically imports the module, gets the class, and instantiates it + using the stored constructor arguments. + """ + fqcn = json_data["class"] # e.g. "module.ClassName" + args = json_data["args"] + mod_name, class_name = fqcn.rsplit(".", 1) + module = importlib.import_module(mod_name) + klass = getattr(module, class_name) + return klass(**args) @abstractmethod def calculate(self, dataset: xr.Dataset) -> Self: From 8bf2d362f0c23a29779245b2e547a7ec39b569d2 Mon Sep 17 00:00:00 2001 From: Tyler Martin Date: Tue, 4 Mar 2025 20:10:17 -0500 Subject: [PATCH 2/8] [feat] adds pipeline reading/writing documentation --- AFL/double_agent/Pipeline.py | 2 + docs/source/how-to/index.rst | 1 + docs/source/how-to/saving_pipelines.ipynb | 261 ++++++++++++++++++++++ 3 files changed, 264 insertions(+) create mode 100644 docs/source/how-to/saving_pipelines.ipynb diff --git a/AFL/double_agent/Pipeline.py b/AFL/double_agent/Pipeline.py index 7d5eaaf..fd5b727 100644 --- a/AFL/double_agent/Pipeline.py +++ b/AFL/double_agent/Pipeline.py @@ -181,6 +181,8 @@ def write_json(self,filename:str,overwrite=False): with open(filename,'w') as f: json.dump(pipeline_dict,f,indent=1) + print(f'Pipeline successfully written to {filename}.') + @staticmethod def read_json(filename: str): """Read pipeline from json file on disk diff --git a/docs/source/how-to/index.rst b/docs/source/how-to/index.rst index 0248c59..ce264d9 100644 --- a/docs/source/how-to/index.rst +++ b/docs/source/how-to/index.rst @@ -9,3 +9,4 @@ Guides for specific tasks building_xarray_datasets create_pipelineop appending + saving_pipelines diff --git a/docs/source/how-to/saving_pipelines.ipynb b/docs/source/how-to/saving_pipelines.ipynb new file mode 100644 index 0000000..59426f3 --- /dev/null +++ b/docs/source/how-to/saving_pipelines.ipynb @@ -0,0 +1,261 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/usnistgov/AFL-agent/blob/main/docs/source/how-to/saving_pipelines.ipynb)\n", + "\n", + "# Reading and Writing Pipelines \n", + "\n", + "Its" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Google Colab Setup\n", + "\n", + "Only uncomment and run the next cell if you are running this notebook in Google Colab or if don't already have the AFL-agent package installed." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# !pip install git+https://github.com/usnistgov/AFL-agent.git" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Writing A Pipeline\n", + "\n", + "To begin, let's load the necessary libraries and define a short pipeline" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "PipelineOp input_variable ---> output_variable\n", + "---------- -----------------------------------\n", + "0 ) measurement ---> derivative\n", + "1 ) derivative ---> similarity\n", + "2 ) similarity ---> labels\n", + "\n", + "Input Variables\n", + "---------------\n", + "0) measurement\n", + "\n", + "Output Variables\n", + "----------------\n", + "0) labels\n" + ] + } + ], + "source": [ + "from AFL.double_agent import *\n", + "\n", + "with Pipeline('MyPipeline') as my_important_pipeline:\n", + "\n", + " SavgolFilter(\n", + " input_variable='measurement', \n", + " output_variable='derivative', \n", + " dim='x', \n", + " derivative=1\n", + " )\n", + "\n", + " Similarity(\n", + " input_variable='derivative', \n", + " output_variable='similarity', \n", + " sample_dim='sample',\n", + " params={'metric': 'laplacian','gamma':1e-4}\n", + " )\n", + " \n", + " SpectralClustering(\n", + " input_variable='similarity',\n", + " output_variable='labels',\n", + " dim='sample',\n", + " params={'n_phases': 2}\n", + " )\n", + "\n", + "my_important_pipeline.print()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now, we can write the pipeline by simply calling the `.write_json()` method" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Pipeline successfully written to pipeline.json.\n" + ] + } + ], + "source": [ + "my_important_pipeline.write_json('pipeline.json')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Excellent! Let's take a look at the json file that was written. We can inspect it using the json module" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'name': 'MyPipeline',\n", + " 'date': '03/04/25 19:59:19-576491',\n", + " 'ops': [{'class': 'AFL.double_agent.Preprocessor.SavgolFilter',\n", + " 'args': {'input_variable': 'measurement',\n", + " 'output_variable': 'derivative',\n", + " 'dim': 'x',\n", + " 'xlo': None,\n", + " 'xhi': None,\n", + " 'xlo_isel': None,\n", + " 'xhi_isel': None,\n", + " 'pedestal': None,\n", + " 'npts': 250,\n", + " 'derivative': 1,\n", + " 'window_length': 31,\n", + " 'polyorder': 2,\n", + " 'apply_log_scale': True,\n", + " 'name': 'SavgolFilter'}},\n", + " {'class': 'AFL.double_agent.PairMetric.Similarity',\n", + " 'args': {'input_variable': 'derivative',\n", + " 'output_variable': 'similarity',\n", + " 'sample_dim': 'sample',\n", + " 'params': {'metric': 'laplacian', 'gamma': 0.0001},\n", + " 'constrain_same': [],\n", + " 'constrain_different': [],\n", + " 'name': 'SimilarityMetric'}},\n", + " {'class': 'AFL.double_agent.Labeler.SpectralClustering',\n", + " 'args': {'input_variable': 'similarity',\n", + " 'output_variable': 'labels',\n", + " 'dim': 'sample',\n", + " 'params': {'n_phases': 2},\n", + " 'name': 'SpectralClustering',\n", + " 'use_silhouette': False}}]}" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import json\n", + "\n", + "with open('pipeline.json','r') as f:\n", + " display(json.load(f))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "With this, we can see that all of the `PipelineOps` are stored in the `ops` keyword with the keyword arguments we specified above. Also included are any default arguments that we didn't explicitly specify. " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Reading a Pipeline\n", + "\n", + "So the next and final step is to load the pipeline from disk." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "PipelineOp input_variable ---> output_variable\n", + "---------- -----------------------------------\n", + "0 ) measurement ---> derivative\n", + "1 ) derivative ---> similarity\n", + "2 ) similarity ---> labels\n", + "\n", + "Input Variables\n", + "---------------\n", + "0) measurement\n", + "\n", + "Output Variables\n", + "----------------\n", + "0) labels\n" + ] + } + ], + "source": [ + "loaded_pipeline = Pipeline.read_json('pipeline.json')\n", + "loaded_pipeline.print()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Success!" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Conclusion" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "venv", + "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.11.10" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} From 09baa6c02b26bc3195733f489bb33e0cd28827ff Mon Sep 17 00:00:00 2001 From: Tyler Martin Date: Thu, 6 Mar 2025 00:02:33 -0500 Subject: [PATCH 3/8] [feat] adds prefabricated pipeline utilities --- .gitignore | 3 +- AFL/double_agent/Pipeline.py | 31 ++-- AFL/double_agent/prefab/__init__.py | 258 ++++++++++++++++++++++++++++ 3 files changed, 276 insertions(+), 16 deletions(-) create mode 100644 AFL/double_agent/prefab/__init__.py diff --git a/.gitignore b/.gitignore index cbe0cf5..dedd1c1 100644 --- a/.gitignore +++ b/.gitignore @@ -18,4 +18,5 @@ docs/source/reference/_autosummary/ objects.inv _build/ .doctrees/ -*.mo \ No newline at end of file +*.mo +AFL-agent.code-workspace diff --git a/AFL/double_agent/Pipeline.py b/AFL/double_agent/Pipeline.py index fd5b727..5ea7fb1 100644 --- a/AFL/double_agent/Pipeline.py +++ b/AFL/double_agent/Pipeline.py @@ -62,17 +62,12 @@ class Pipeline(PipelineContext): Edge labels for the pipeline graph visualization """ - def __init__(self, name: Optional[str] = None, ops: Optional[List] = None) -> None: + def __init__(self, name: Optional[str] = None, ops: Optional[List] = None, description: Optional[str] = None) -> None: self.result = None - if ops is None: - self.ops = [] - else: - self.ops = ops + self.ops = ops or [] + self.description = str(description) + self.name = name or "Pipeline" - if name is None: - self.name = "Pipeline" - else: - self.name = name # placeholder for networkx graph self.graph = None @@ -160,26 +155,31 @@ def clear_outputs(self): def copy(self) -> Self: return copy.deepcopy(self) - def write_json(self,filename:str,overwrite=False): + def write_json(self, filename: str, overwrite=False, description: Optional[str] = None): """Write pipeline to disk as a JSON Parameters ---------- filename: str Filename or filepath to be written + overwrite: bool, default=False + Whether to overwrite an existing file + description: str, optional + A descriptive text about the pipeline's purpose and functionality """ if not overwrite and pathlib.Path(filename).exists(): raise FileExistsError() pipeline_dict = { - 'name':self.name, + 'name': self.name, 'date': datetime.datetime.now().strftime('%m/%d/%y %H:%M:%S-%f'), - 'ops':[op.to_json() for op in self] + 'description': str(description) if description is not None else self.description, + 'ops': [op.to_json() for op in self] } - with open(filename,'w') as f: - json.dump(pipeline_dict,f,indent=1) + with open(filename, 'w') as f: + json.dump(pipeline_dict, f, indent=1) print(f'Pipeline successfully written to {filename}.') @@ -199,7 +199,8 @@ def read_json(filename: str): pipeline = Pipeline( name=pipeline_dict['name'], - ops=[PipelineOp.from_json(op) for op in pipeline_dict['ops']] + ops=[PipelineOp.from_json(op) for op in pipeline_dict['ops']], + description=pipeline_dict['description'] ) return pipeline diff --git a/AFL/double_agent/prefab/__init__.py b/AFL/double_agent/prefab/__init__.py new file mode 100644 index 0000000..b8d36b3 --- /dev/null +++ b/AFL/double_agent/prefab/__init__.py @@ -0,0 +1,258 @@ +""" +Prefabricated Pipelines module for AFL.double_agent. + +This module provides access to prefabricated pipelines that can be used with AFL.double_agent. +It allows loading, listing, and combining multiple pipelines into a single pipeline. +""" + +import os +import pathlib +import warnings +import json +from typing import List, Dict, Optional, Union + +import xarray as xr + +from AFL.double_agent.Pipeline import Pipeline + +# Get the path to the prefab directory +def get_prefab_dir(): + """ + Get the path to the prefabricated pipelines directory. + + Returns + ------- + pathlib.Path + Path to the prefab directory. + """ + # The prefab directory is located in AFL/double_agent/prefab + module_dir = pathlib.Path(__file__).parent + prefab_dir = module_dir + + if not prefab_dir.exists(): + warnings.warn(f"Prefab directory not found at {prefab_dir}") + + return prefab_dir + +def list_prefabs(display_table: bool = True): + """ + List all available prefabricated pipelines. + + Parameters + ---------- + display_table : bool, default=True + Whether to display the results in a formatted table with descriptions. + If False, returns just the list of prefab names. + + Returns + ------- + list or None + If display_table is False, returns a list of available prefabricated pipeline names. + If display_table is True, prints a formatted table and returns None. + """ + prefab_dir = get_prefab_dir() + if not prefab_dir.exists(): + warnings.warn(f"Prefab directory not found at {prefab_dir}") + return [] + + prefab_files = list(prefab_dir.glob("*.json")) + + if not display_table: + return [f.stem for f in prefab_files] + + if not prefab_files: + print("No prefabricated pipelines found.") + return None + + # Get descriptions from each prefab file + prefabs_info = [] + max_name_len = 4 # Minimum width for "Name" column + max_desc_len = 11 # Minimum width for "Description" column + + for file_path in prefab_files: + try: + with open(file_path, 'r') as f: + prefab_data = json.load(f) + + name = file_path.stem + description = prefab_data.get('description', 'No description available') + + # Track maximum lengths for formatting + max_name_len = max(max_name_len, len(name)) + max_desc_len = max(max_desc_len, len(description)) + + prefabs_info.append((name, description)) + except Exception as e: + warnings.warn(f"Error reading prefab {file_path.name}: {str(e)}") + + # Print formatted table + header = f"| {'Name':<{max_name_len}} | {'Description':<{max_desc_len}} |" + separator = f"|-{'-'*max_name_len}-|-{'-'*max_desc_len}-|" + + print("\nAvailable Prefabricated Pipelines:") + print(separator) + print(header) + print(separator) + + for name, description in sorted(prefabs_info): + print(f"| {name:<{max_name_len}} | {description:<{max_desc_len}} |") + + print(separator) + print(f"Total: {len(prefabs_info)} prefabricated pipeline(s)") + + return None + +def load_prefab(name: str) -> Pipeline: + """ + Load a prefabricated pipeline by name. + + Parameters + ---------- + name : str + Name of the prefabricated pipeline to load. + + Returns + ------- + Pipeline + The loaded pipeline. + + Raises + ------ + FileNotFoundError + If the prefabricated pipeline does not exist. + """ + prefab_dir = get_prefab_dir() + file_path = prefab_dir / f"{name}.json" + + if not file_path.exists(): + raise FileNotFoundError( + f"Prefabricated pipeline '{name}' not found at {file_path}. " + f"Prefab directory: {prefab_dir}. " + f"Available prefabs: {list_prefabs()}" + ) + + return Pipeline.read_json(str(file_path)) + +def combine_prefabs(prefab_names: List[str], new_name: Optional[str] = None) -> Pipeline: + """ + Combine multiple prefabricated pipelines into a single pipeline. + + Parameters + ---------- + prefab_names : List[str] + List of prefabricated pipeline names to combine. + new_name : Optional[str], default=None + Name for the combined pipeline. If None, a name will be generated from the component pipelines. + + Returns + ------- + Pipeline + The combined pipeline. + + Raises + ------ + FileNotFoundError + If any of the prefabricated pipelines do not exist. + ValueError + If no prefabricated pipelines are provided. + """ + if not prefab_names: + raise ValueError("No prefabricated pipelines provided for combination.") + + if len(prefab_names) == 1: + return load_prefab(prefab_names[0]) + + # Generate a combined name if not provided + if new_name is None: + new_name = f"Combined_{'_'.join(prefab_names)}" + + # Load all pipelines + pipelines = [load_prefab(name) for name in prefab_names] + + # Create a new pipeline with the first pipeline's ops + combined_pipeline = pipelines[0].copy() + combined_pipeline.name = new_name + + # Add all operations from subsequent pipelines + for pipeline in pipelines[1:]: + combined_pipeline.extend(pipeline.ops) + + return combined_pipeline + +def save_prefab(pipeline: Pipeline, name: Optional[str] = None, overwrite: bool = False, description: Optional[str] = None) -> str: + """ + Save a pipeline as a prefabricated pipeline. + + Parameters + ---------- + pipeline : Pipeline + The pipeline to save. + name : Optional[str], default=None + Name to save the pipeline as. If None, uses the pipeline's name. + overwrite : bool, default=False + Whether to overwrite an existing prefabricated pipeline with the same name. + description : Optional[str], default=None + A descriptive text about the pipeline's purpose and functionality. + If None and pipeline has a description attribute, that will be used. + + Returns + ------- + str + The path to the saved prefabricated pipeline file. + + Raises + ------ + FileExistsError + If a prefabricated pipeline with the given name already exists and overwrite=False. + """ + prefab_dir = get_prefab_dir() + + # Use the pipeline's name if no name is provided + if name is None: + name = pipeline.name + + # Use the pipeline's description if available and none provided + if description is None and hasattr(pipeline, 'description'): + description = pipeline.description + + # Ensure valid filename + name = name.replace(" ", "_") + file_path = prefab_dir / f"{name}.json" + + # Check if file exists and overwrite is not allowed + if file_path.exists() and not overwrite: + raise FileExistsError( + f"Prefabricated pipeline '{name}' already exists at {file_path}. " + f"Use overwrite=True to overwrite." + ) + + # Save the pipeline with description + pipeline.write_json(str(file_path), overwrite=True, description=description) + + return str(file_path) + +# Define any example prefabs that should be available by default +def example_prefab1(): + """ + Load an example prefabricated pipeline. + + Returns + ------- + Pipeline + An example prefabricated pipeline. + """ + try: + return load_prefab("example_prefab") + except FileNotFoundError: + warnings.warn("Example prefab not found. You may need to create example prefabs.") + return Pipeline(name="empty_example") + +# Export public functions +__all__ = [ + "get_prefab_dir", + "list_prefabs", + "load_prefab", + "combine_prefabs", + "save_prefab", + "example_prefab1" +] \ No newline at end of file From 2a0479f20db5779f3f0a9403fb526235ff35bb5e Mon Sep 17 00:00:00 2001 From: Tyler Martin Date: Thu, 6 Mar 2025 19:55:42 -0500 Subject: [PATCH 4/8] [refactor] converts transforms to strings in constructor --- AFL/double_agent/Preprocessor.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/AFL/double_agent/Preprocessor.py b/AFL/double_agent/Preprocessor.py index 894c1d7..810b9a7 100644 --- a/AFL/double_agent/Preprocessor.py +++ b/AFL/double_agent/Preprocessor.py @@ -742,6 +742,9 @@ def __init__( name: str = "SympyTransform", ) -> None: + # must convert to strings for JSON serialization + transforms = {k:str(v) for k,v in transforms.items()} + super().__init__( name=name, input_variable=input_variable, output_variable=output_variable ) @@ -765,6 +768,7 @@ def calculate(self, dataset: xr.Dataset) -> Self: # apply transform new_comps = xr.Dataset() for name, transform in self.transforms.items(): + transform = sympy.sympify(transform) symbols = list(transform.free_symbols) lam = sympy.lambdify(symbols, transform) new_comps[name] = ( From 630ed07ca69709303782ece90685317ca63c9a26 Mon Sep 17 00:00:00 2001 From: Tyler Martin Date: Thu, 6 Mar 2025 20:57:32 -0500 Subject: [PATCH 5/8] [refactor] changes kernel handling for extrapolators for JSON serializability --- AFL/double_agent/Extrapolator.py | 64 ++++++++++++++------------------ 1 file changed, 28 insertions(+), 36 deletions(-) diff --git a/AFL/double_agent/Extrapolator.py b/AFL/double_agent/Extrapolator.py index 186f386..3e7af4f 100644 --- a/AFL/double_agent/Extrapolator.py +++ b/AFL/double_agent/Extrapolator.py @@ -13,7 +13,7 @@ - Support for different sample and grid dimensions """ -from typing import List, Optional +from typing import List import numpy as np import sklearn.gaussian_process # type: ignore @@ -260,9 +260,12 @@ class predictions and uncertainty estimates through entropy. The `xarray` dimension over the discrete 'samples' in the `feature_input_variable`. This is typically a variant of `sample` e.g., `saxs_sample`. - kernel: Optional[object] - A optional sklearn.gaussian_process.kernel to use the classifier. If not provided, will default to + kernel: str + The name of the sklearn.gaussian_process.kernel to use the classifier. If not provided, will default to `Matern`. + + kernel_kwargs: dict + Additional keyword arguments to pass to the sklearn.gaussian_process.kernel optimizer: str The name of the optimizer to use in optimizer the gaussian process parameters @@ -279,7 +282,8 @@ def __init__( grid_variable: str, grid_dim: str, sample_dim: str, - kernel: Optional[object] = None, + kernel: str = 'Matern', + kernel_kwargs: dict = {'length_scale':1.0, 'nu':1.5}, optimizer: str = "fmin_l_bfgs_b", name: str = "GaussianProcessClassifier", ) -> None: @@ -294,19 +298,11 @@ def __init__( grid_dim=grid_dim, sample_dim=sample_dim, ) - - if kernel is None: - self.kernel = sklearn.gaussian_process.kernels.Matern( - length_scale=1.0, nu=1.5 - ) - else: - self.kernel = kernel - + self.kernel = kernel + self.kernel_kwargs = kernel_kwargs self.output_prefix = output_prefix - if optimizer is not None: - self.optimizer = optimizer - else: - self.optimizer = None + self.optimizer = optimizer + def calculate(self, dataset: xr.Dataset) -> Self: """Apply this GP classifier to the supplied dataset. @@ -341,8 +337,10 @@ def calculate(self, dataset: xr.Dataset) -> Self: ) else: + kernel = getattr(sklearn.gaussian_process.kernels, self.kernel)(**self.kernel_kwargs) + clf = sklearn.gaussian_process.GaussianProcessClassifier( - kernel=self.kernel, optimizer=self.optimizer + kernel=kernel, optimizer=self.optimizer ).fit(X.values, y.values) # entropy approach to classification probabilities @@ -395,14 +393,14 @@ class GaussianProcessRegressor(Extrapolator): The `xarray` dimension over the discrete 'samples' in the `feature_input_variable`. This is typically a variant of `sample` e.g., `saxs_sample`. - predictor_uncertainty_variable: Optional[str] + predictor_uncertainty_variable: str | None Variable containing uncertainty estimates for the predictor values optimizer: str The name of the optimizer to use in optimizer the gaussian process parameters - kernel: Optional[object] - A optional sklearn.gaussian_process.kernel to use the regressor. If not provided, will default to + kernel: str | None + The name of the sklearn.gaussian_process.kernel to use the regressor. If not provided, will default to `Matern`. name: str @@ -422,7 +420,8 @@ def __init__( sample_dim, predictor_uncertainty_variable=None, optimizer="fmin_l_bfgs_b", - kernel=None, + kernel: str = 'Matern', + kernel_kwargs: dict = {'length_scale':1.0, 'nu':1.5}, name="GaussianProcessRegressor", fix_nans=True, ) -> None: @@ -440,19 +439,10 @@ def __init__( self.predictor_uncertainty_variable = predictor_uncertainty_variable if predictor_uncertainty_variable is not None: self.input_variable.append(predictor_uncertainty_variable) - - if kernel is None: - self.kernel = sklearn.gaussian_process.kernels.Matern( - #length_scale=[0.1], length_scale_bounds=(1e-3, 1e0), nu=1.5 - length_scale = [0.1], length_scale_bounds = (0.2, 1e0), nu = 1.5 - ) - else: - self.kernel = kernel - - if optimizer is not None: - self.optimizer = optimizer - else: - self.optimizer = "fmin_l_bfgs_b" + + self.kernel = kernel + self.kernel_kwargs = kernel_kwargs + self.optimizer = optimizer self.predictor_uncertainty_variable = predictor_uncertainty_variable self._banned_from_attrs.append("predictor_uncertainty_variable") @@ -491,15 +481,17 @@ def calculate(self, dataset: xr.Dataset) -> Self: dy = dataset[self.predictor_uncertainty_variable].transpose( self.sample_dim, ... ) + kernel = getattr(sklearn.gaussian_process.kernels, self.kernel)(**self.kernel_kwargs) reg = sklearn.gaussian_process.GaussianProcessRegressor( - kernel=self.kernel, alpha=dy.values, optimizer=self.optimizer + kernel=kernel, alpha=dy.values, optimizer=self.optimizer ).fit(X.values, y.values) reg_type = "heteroscedastic" else: + kernel = getattr(sklearn.gaussian_process.kernels, self.kernel)(**self.kernel_kwargs) reg = sklearn.gaussian_process.GaussianProcessRegressor( - kernel=self.kernel, optimizer=self.optimizer + kernel=kernel, optimizer=self.optimizer ).fit(X.values, y.values) reg_type = "homoscedastic" From d795555bbb6f3c95b1c1dfdaee35d38c89c7b821 Mon Sep 17 00:00:00 2001 From: Tyler Martin Date: Thu, 6 Mar 2025 20:58:14 -0500 Subject: [PATCH 6/8] [feat] adds first prefab pipelines --- AFL/double_agent/Preprocessor.py | 32 ++--- AFL/double_agent/TensorFlowExtrapolator.py | 25 ++-- AFL/double_agent/__init__.py | 2 + AFL/double_agent/data/__init__.py | 11 +- AFL/double_agent/prefab/__init__.py | 12 +- AFL/double_agent/prefab/find_boundaries.json | 129 ++++++++++++++++++ AFL/double_agent/prefab/preprocess.json | 123 +++++++++++++++++ .../prefab/similarity_clustering.json | 35 +++++ 8 files changed, 328 insertions(+), 41 deletions(-) create mode 100644 AFL/double_agent/prefab/find_boundaries.json create mode 100644 AFL/double_agent/prefab/preprocess.json create mode 100644 AFL/double_agent/prefab/similarity_clustering.json diff --git a/AFL/double_agent/Preprocessor.py b/AFL/double_agent/Preprocessor.py index 810b9a7..513a54a 100644 --- a/AFL/double_agent/Preprocessor.py +++ b/AFL/double_agent/Preprocessor.py @@ -324,14 +324,14 @@ class Standardize(Preprocessor): The name of the variable to be inserted into the `xarray.Dataset` by this `PipelineOp` dim : str The dimension used for calculating the data minimum - component_dim : Optional[str], default="component" + component_dim : str | None, default="component" The dimension for component-wise operations - scale_variable : Optional[str], default=None + scale_variable : str | None, default=None If specified, the min/max of this data variable in the supplied `xarray.Dataset` will be used to scale the data rather than min/max of the `input_variable` or the supplied `min_val` or `max_val` - min_val : Optional[Number], default=None + min_val : Number | None, default=None Value used to scale the data minimum - max_val : Optional[Number], default=None + max_val : Number | None, default=None Value used to scale the data maximum name : str, default="Standardize" The name to use when added to a Pipeline @@ -342,10 +342,10 @@ def __init__( input_variable: str, output_variable: str, dim: str, - component_dim: Optional[str] = "component", - scale_variable: Optional[str] = None, - min_val: Optional[Number] = None, - max_val: Optional[Number] = None, + component_dim: str | None = "component", + scale_variable: str | None = None, + min_val: Number | None = None, + max_val: Number | None = None, name: str = "Standardize", ) -> None: super().__init__( @@ -401,14 +401,14 @@ class Destandardize(Preprocessor): The name of the variable to be inserted into the `xarray.Dataset` by this `PipelineOp` dim : str The dimension used for calculating the data minimum - component_dim : Optional[str], default="component" + component_dim : str | None, default="component" The dimension for component-wise operations - scale_variable : Optional[str], default=None + scale_variable : str | None, default=None If specified, the min/max of this data variable in the supplied `xarray.Dataset` will be used to scale the data rather than min/max of the `input_variable` or the supplied `min_val` or `max_val` - min_val : Optional[Number], default=None + min_val : Number | None, default=None Value used to scale the data minimum - max_val : Optional[Number], default=None + max_val : Number | None, default=None Value used to scale the data maximum name : str, default="Destandardize" The name to use when added to a Pipeline @@ -419,10 +419,10 @@ def __init__( input_variable: str, output_variable: str, dim: str, - component_dim: Optional[str] = "component", - scale_variable: Optional[str] = None, - min_val: Optional[Number] = None, - max_val: Optional[Number] = None, + component_dim: str | None = "component", + scale_variable: str | None = None, + min_val: Number | None = None, + max_val: Number | None = None, name: str = "Destandardize", ) -> None: diff --git a/AFL/double_agent/TensorFlowExtrapolator.py b/AFL/double_agent/TensorFlowExtrapolator.py index 3dc8e63..185142c 100644 --- a/AFL/double_agent/TensorFlowExtrapolator.py +++ b/AFL/double_agent/TensorFlowExtrapolator.py @@ -4,7 +4,7 @@ This file segments all extapolators that require tensorflow. """ -from typing import List, Optional +from typing import List from typing_extensions import Self import numpy as np @@ -114,7 +114,8 @@ def __init__( grid_dim: str, sample_dim: str, optimize: bool = True, - kernel: Optional[gpflow.kernels.Kernel] = None, + kernel: str = 'Matern32', + kernel_kwargs: dict = {'lengthscales':0.1, 'variance':0.1}, name: str = "TFGaussianProcessClassifier", ) -> None: """ @@ -141,9 +142,12 @@ def __init__( The `xarray` dimension over the discrete 'samples' in the `feature_input_variable`. This is typically a variant of `sample` e.g., `saxs_sample`. - kernel: Optional[object] - A optional sklearn.gaussian_process.kernel to use the classifier. If not provided, will default to - `Matern`. + kernel: str | None + The name of the sklearn.gaussian_process.kernel to use the classifier. If not provided, will default to + `Matern32`. + + kernel_kwargs: dict | None + Additional keyword arguments to pass to the sklearn.gaussian_process.kernel name: str The name to use when added to a Pipeline. This name is used when calling Pipeline.search() @@ -161,12 +165,8 @@ def __init__( optimize=optimize, ) - if kernel is None: - self.kernel: gpflow.kernels.Kernel = gpflow.kernels.Matern32( - variance=0.1, lengthscales=0.1 - ) - else: - self.kernel = kernel + self.kernel = kernel + self.kernel_kwargs = kernel_kwargs self.output_prefix = output_prefix @@ -191,9 +191,10 @@ def calculate(self, dataset: xr.Dataset) -> Self: invlink = gpflow.likelihoods.RobustMax(n_classes) likelihood = gpflow.likelihoods.MultiClass(n_classes, invlink=invlink) + kernel = getattr(gpflow.kernels, self.kernel)(**self.kernel_kwargs) model = gpflow.models.VGP( data=data, - kernel=self.kernel, + kernel=kernel, likelihood=likelihood, num_latent_gps=n_classes, ) diff --git a/AFL/double_agent/__init__.py b/AFL/double_agent/__init__.py index c360f76..829f01a 100644 --- a/AFL/double_agent/__init__.py +++ b/AFL/double_agent/__init__.py @@ -7,6 +7,8 @@ from .Generator import * from .plotting import * from .Boundary import * +from .prefab import * +from .data import * import os import subprocess diff --git a/AFL/double_agent/data/__init__.py b/AFL/double_agent/data/__init__.py index 0984dc9..79fae98 100644 --- a/AFL/double_agent/data/__init__.py +++ b/AFL/double_agent/data/__init__.py @@ -6,13 +6,12 @@ import os import pathlib -import importlib.resources import warnings import xarray as xr # Get the path to the data directory -def get_data_dir(): +def get_data_dir() -> pathlib.Path: """ Get the path to the data directory. @@ -23,14 +22,14 @@ def get_data_dir(): """ # The data directory is now located in AFL/double_agent/data module_dir = pathlib.Path(__file__).parent - data_dir = module_dir#.parent / "data" + data_dir = module_dir if not data_dir.exists(): warnings.warn(f"Data directory not found at {data_dir}") return data_dir -def list_datasets(): +def list_datasets() -> list[str]: """ List all available datasets. @@ -46,7 +45,7 @@ def list_datasets(): return [f.stem for f in data_dir.glob("*.nc")] -def load_dataset(name): +def load_dataset(name: str) -> xr.Dataset: """ Load a dataset by name. @@ -78,7 +77,7 @@ def load_dataset(name): return xr.open_dataset(file_path) # Define specific dataset loaders -def example_dataset1(): +def example_dataset1() -> xr.Dataset: """ Load the example dataset. diff --git a/AFL/double_agent/prefab/__init__.py b/AFL/double_agent/prefab/__init__.py index b8d36b3..0830e13 100644 --- a/AFL/double_agent/prefab/__init__.py +++ b/AFL/double_agent/prefab/__init__.py @@ -11,8 +11,6 @@ import json from typing import List, Dict, Optional, Union -import xarray as xr - from AFL.double_agent.Pipeline import Pipeline # Get the path to the prefab directory @@ -133,7 +131,7 @@ def load_prefab(name: str) -> Pipeline: return Pipeline.read_json(str(file_path)) -def combine_prefabs(prefab_names: List[str], new_name: Optional[str] = None) -> Pipeline: +def combine_prefabs(prefab_names: List[str], new_name: str | None = None) -> Pipeline: """ Combine multiple prefabricated pipelines into a single pipeline. @@ -141,7 +139,7 @@ def combine_prefabs(prefab_names: List[str], new_name: Optional[str] = None) -> ---------- prefab_names : List[str] List of prefabricated pipeline names to combine. - new_name : Optional[str], default=None + new_name : str | None, default=None Name for the combined pipeline. If None, a name will be generated from the component pipelines. Returns @@ -179,7 +177,7 @@ def combine_prefabs(prefab_names: List[str], new_name: Optional[str] = None) -> return combined_pipeline -def save_prefab(pipeline: Pipeline, name: Optional[str] = None, overwrite: bool = False, description: Optional[str] = None) -> str: +def save_prefab(pipeline: Pipeline, name: str | None = None, overwrite: bool = False, description: str | None = None) -> str: """ Save a pipeline as a prefabricated pipeline. @@ -187,11 +185,11 @@ def save_prefab(pipeline: Pipeline, name: Optional[str] = None, overwrite: bool ---------- pipeline : Pipeline The pipeline to save. - name : Optional[str], default=None + name : str | None, default=None Name to save the pipeline as. If None, uses the pipeline's name. overwrite : bool, default=False Whether to overwrite an existing prefabricated pipeline with the same name. - description : Optional[str], default=None + description : str | None, default=None A descriptive text about the pipeline's purpose and functionality. If None and pipeline has a description attribute, that will be used. diff --git a/AFL/double_agent/prefab/find_boundaries.json b/AFL/double_agent/prefab/find_boundaries.json new file mode 100644 index 0000000..f81b37b --- /dev/null +++ b/AFL/double_agent/prefab/find_boundaries.json @@ -0,0 +1,129 @@ +{ + "name": "find_boundaries", + "date": "03/06/25 20:30:14-992001", + "description": "A simlarity-clustering-classification pipeline for finding boundaries in measurement data", + "ops": [ + { + "class": "AFL.double_agent.Preprocessor.Standardize", + "args": { + "input_variable": "composition", + "output_variable": "normalized_composition", + "dim": "sample", + "component_dim": "component", + "scale_variable": null, + "min_val": { + "A": 0.0, + "B": 0.0 + }, + "max_val": { + "A": 10.0, + "B": 25.0 + }, + "name": "Standardize" + } + }, + { + "class": "AFL.double_agent.Preprocessor.Standardize", + "args": { + "input_variable": "composition_grid", + "output_variable": "normalized_composition_grid", + "dim": "grid", + "component_dim": "component", + "scale_variable": null, + "min_val": { + "A": 0.0, + "B": 0.0 + }, + "max_val": { + "A": 10.0, + "B": 25.0 + }, + "name": "Standardize" + } + }, + { + "class": "AFL.double_agent.Preprocessor.SavgolFilter", + "args": { + "input_variable": "measurement", + "output_variable": "derivative", + "dim": "x", + "xlo": null, + "xhi": null, + "xlo_isel": null, + "xhi_isel": null, + "pedestal": null, + "npts": 250, + "derivative": 1, + "window_length": 31, + "polyorder": 2, + "apply_log_scale": true, + "name": "SavgolFilter" + } + }, + { + "class": "AFL.double_agent.PairMetric.Similarity", + "args": { + "input_variable": "derivative", + "output_variable": "similarity", + "sample_dim": "sample", + "params": { + "metric": "laplacian", + "gamma": 0.0001 + }, + "constrain_same": [], + "constrain_different": [], + "name": "SimilarityMetric" + } + }, + { + "class": "AFL.double_agent.Labeler.SpectralClustering", + "args": { + "input_variable": "similarity", + "output_variable": "labels", + "dim": "sample", + "params": { + "n_phases": 2 + }, + "name": "SpectralClustering", + "use_silhouette": false + } + }, + { + "class": "AFL.double_agent.Extrapolator.GaussianProcessClassifier", + "args": { + "feature_input_variable": "normalized_composition", + "predictor_input_variable": "labels", + "output_prefix": "extrap", + "grid_variable": "normalized_composition_grid", + "grid_dim": "grid", + "sample_dim": "sample", + "kernel": "Matern", + "kernel_kwargs": { + "length_scale": 1.0, + "nu": 1.5 + }, + "optimizer": "fmin_l_bfgs_b", + "name": "GaussianProcessClassifier" + } + }, + { + "class": "AFL.double_agent.AcquisitionFunction.MaxValueAF", + "args": { + "input_variables": [ + "extrap_entropy" + ], + "grid_variable": "composition_grid", + "grid_dim": "grid", + "combine_coeffs": null, + "output_prefix": null, + "output_variable": "next_sample", + "decision_rtol": 0.05, + "excluded_comps_variables": null, + "excluded_comps_dim": null, + "exclusion_radius": 0.001, + "count": 1, + "name": "MaxValueAF" + } + } + ] +} \ No newline at end of file diff --git a/AFL/double_agent/prefab/preprocess.json b/AFL/double_agent/prefab/preprocess.json new file mode 100644 index 0000000..a1c422f --- /dev/null +++ b/AFL/double_agent/prefab/preprocess.json @@ -0,0 +1,123 @@ +{ + "name": "preprocess", + "date": "03/06/25 20:55:30-351053", + "description": "A pipeline that generates a Cartesian grid, normalizes data, and calculates derivatives using Savgol filter", + "ops": [ + { + "class": "AFL.double_agent.Generator.CartesianGrid", + "args": { + "output_variable": "composition_grid", + "grid_spec": { + "A": { + "min": 0.0, + "max": 10.0, + "steps": 50 + }, + "B": { + "min": 0.0, + "max": 25.0, + "steps": 50 + } + }, + "sample_dim": "grid", + "component_dim": "component", + "name": "CartesianGridGenerator" + } + }, + { + "class": "AFL.double_agent.Preprocessor.Standardize", + "args": { + "input_variable": "composition_grid", + "output_variable": "normalized_composition_grid", + "dim": "grid", + "component_dim": "component", + "scale_variable": null, + "min_val": { + "A": 0.0, + "B": 0.0 + }, + "max_val": { + "A": 10.0, + "B": 25.0 + }, + "name": "Standardize" + } + }, + { + "class": "AFL.double_agent.Preprocessor.Standardize", + "args": { + "input_variable": "composition", + "output_variable": "normalized_composition", + "dim": "sample", + "component_dim": "component", + "scale_variable": null, + "min_val": { + "A": 0.0, + "B": 0.0 + }, + "max_val": { + "A": 10.0, + "B": 25.0 + }, + "name": "Standardize" + } + }, + { + "class": "AFL.double_agent.Preprocessor.SavgolFilter", + "args": { + "input_variable": "measurement", + "output_variable": "measurement_derivative0", + "dim": "q", + "xlo": null, + "xhi": null, + "xlo_isel": null, + "xhi_isel": null, + "pedestal": null, + "npts": 250, + "derivative": 0, + "window_length": 31, + "polyorder": 2, + "apply_log_scale": true, + "name": "SavgolFilter" + } + }, + { + "class": "AFL.double_agent.Preprocessor.SavgolFilter", + "args": { + "input_variable": "measurement", + "output_variable": "measurement_derivative1", + "dim": "q", + "xlo": null, + "xhi": null, + "xlo_isel": null, + "xhi_isel": null, + "pedestal": null, + "npts": 250, + "derivative": 1, + "window_length": 31, + "polyorder": 2, + "apply_log_scale": true, + "name": "SavgolFilter" + } + }, + { + "class": "AFL.double_agent.Preprocessor.SavgolFilter", + "args": { + "input_variable": "measurement", + "output_variable": "measurement_derivative2", + "dim": "q", + "xlo": null, + "xhi": null, + "xlo_isel": null, + "xhi_isel": null, + "pedestal": null, + "npts": 250, + "derivative": 2, + "window_length": 31, + "polyorder": 2, + "apply_log_scale": true, + "name": "SavgolFilter" + } + } + ] +} \ No newline at end of file diff --git a/AFL/double_agent/prefab/similarity_clustering.json b/AFL/double_agent/prefab/similarity_clustering.json new file mode 100644 index 0000000..56153d4 --- /dev/null +++ b/AFL/double_agent/prefab/similarity_clustering.json @@ -0,0 +1,35 @@ +{ + "name": "similarity_clustering", + "date": "03/06/25 20:38:57-760847", + "description": "A simlarity-clustering pipeline for clustering measurements into groups", + "ops": [ + { + "class": "AFL.double_agent.PairMetric.Similarity", + "args": { + "input_variable": "measurement", + "output_variable": "similarity", + "sample_dim": "sample", + "params": { + "metric": "laplacian", + "gamma": 0.0001 + }, + "constrain_same": [], + "constrain_different": [], + "name": "SimilarityMetric" + } + }, + { + "class": "AFL.double_agent.Labeler.SpectralClustering", + "args": { + "input_variable": "similarity", + "output_variable": "labels", + "dim": "sample", + "params": { + "n_phases": 2 + }, + "name": "SpectralClustering", + "use_silhouette": false + } + } + ] +} \ No newline at end of file From f33816534b4233314c7537448b3146c4f94a85fc Mon Sep 17 00:00:00 2001 From: Tyler Martin Date: Fri, 7 Mar 2025 23:44:54 -0500 Subject: [PATCH 7/8] [feat] print_code() not prints into a Jupyter Notebook cell --- AFL/double_agent/Pipeline.py | 65 ++++++++++++++++++++++++------------ 1 file changed, 44 insertions(+), 21 deletions(-) diff --git a/AFL/double_agent/Pipeline.py b/AFL/double_agent/Pipeline.py index 5ea7fb1..8549076 100644 --- a/AFL/double_agent/Pipeline.py +++ b/AFL/double_agent/Pipeline.py @@ -37,19 +37,19 @@ class Pipeline(PipelineContext): """ Container class for defining and executing computational workflows. - + The Pipeline class serves as a framework for organizing and running sequences of operations (PipelineOps) on data. Each operation in the pipeline takes input data, performs a specific transformation, and produces output data that can be used by subsequent operations. - + Parameters ---------- name : Optional[str], default=None Name of the pipeline. If None, defaults to "Pipeline". ops : Optional[List], default=None List of PipelineOp objects to initialize the pipeline with. - + Attributes ---------- result : Any @@ -62,13 +62,17 @@ class Pipeline(PipelineContext): Edge labels for the pipeline graph visualization """ - def __init__(self, name: Optional[str] = None, ops: Optional[List] = None, description: Optional[str] = None) -> None: + def __init__( + self, + name: Optional[str] = None, + ops: Optional[List] = None, + description: Optional[str] = None, + ) -> None: self.result = None self.ops = ops or [] self.description = str(description) self.name = name or "Pipeline" - # placeholder for networkx graph self.graph = None self.graph_edge_labels = None @@ -118,12 +122,11 @@ def print_code(self) -> None: """String representation of approximate code to generate this pipeline Run this method to produce a string of Python code that should - recreate this Pipeline. + recreate this Pipeline. """ - - output_string = f"with Pipeline(name = \"{self.name}\") as p:\n" + output_string = f'with Pipeline(name = "{self.name}") as p:\n' for op in self: args = op._stored_args @@ -135,7 +138,24 @@ def print_code(self) -> None: output_string += f" {k}={v},\n" output_string += f" )\n\n" - print(output_string) + try: + shell = get_ipython().__class__.__name__ + if shell == "ZMQInteractiveShell": + # Create IPython magic for creating executable code + ip = get_ipython() + + # First display the code with syntax highlighting for visibility + from IPython.display import display, Code + + # display(Code(output_string, language="python")) + + # Define a temporary magic to create a new cell with the code + ip.set_next_input(output_string) + print("Pipeline code has been prepared in a new cell below.") + else: + print(output_string) + except NameError: + print(output_string) def append(self, op: PipelineOp) -> Self: """Mirrors the behavior of python lists""" @@ -154,8 +174,10 @@ def clear_outputs(self): def copy(self) -> Self: return copy.deepcopy(self) - - def write_json(self, filename: str, overwrite=False, description: Optional[str] = None): + + def write_json( + self, filename: str, overwrite=False, description: Optional[str] = None + ): """Write pipeline to disk as a JSON Parameters @@ -172,16 +194,18 @@ def write_json(self, filename: str, overwrite=False, description: Optional[str] raise FileExistsError() pipeline_dict = { - 'name': self.name, - 'date': datetime.datetime.now().strftime('%m/%d/%y %H:%M:%S-%f'), - 'description': str(description) if description is not None else self.description, - 'ops': [op.to_json() for op in self] + "name": self.name, + "date": datetime.datetime.now().strftime("%m/%d/%y %H:%M:%S-%f"), + "description": ( + str(description) if description is not None else self.description + ), + "ops": [op.to_json() for op in self], } - with open(filename, 'w') as f: + with open(filename, "w") as f: json.dump(pipeline_dict, f, indent=1) - print(f'Pipeline successfully written to {filename}.') + print(f"Pipeline successfully written to {filename}.") @staticmethod def read_json(filename: str): @@ -198,14 +222,13 @@ def read_json(filename: str): pipeline_dict = json.load(f) pipeline = Pipeline( - name=pipeline_dict['name'], - ops=[PipelineOp.from_json(op) for op in pipeline_dict['ops']], - description=pipeline_dict['description'] + name=pipeline_dict["name"], + ops=[PipelineOp.from_json(op) for op in pipeline_dict["ops"]], + description=pipeline_dict["description"], ) return pipeline - def write_pkl(self, filename: str): """Write pipeline to disk as a pkl From e49747a37d07f04eea8ce30e9e6565900485502f Mon Sep 17 00:00:00 2001 From: Tyler Martin Date: Sat, 8 Mar 2025 00:03:47 -0500 Subject: [PATCH 8/8] [docs] adds tutorial for using prefab pipelines --- AFL/double_agent/PipelineOp.py | 117 +- AFL/double_agent/data/__init__.py | 29 +- docs/source/tutorials/index.rst | 3 +- docs/source/tutorials/using_prefab.ipynb | 1502 ++++++++++++++++++++++ 4 files changed, 1587 insertions(+), 64 deletions(-) create mode 100644 docs/source/tutorials/using_prefab.ipynb diff --git a/AFL/double_agent/PipelineOp.py b/AFL/double_agent/PipelineOp.py index d63f9df..a5a52e3 100644 --- a/AFL/double_agent/PipelineOp.py +++ b/AFL/double_agent/PipelineOp.py @@ -30,20 +30,25 @@ class PipelineOp(ABC): Prefix for output variables when using pattern matching """ - def __init__(self, - name: Optional[str] | List[str] = None, - input_variable: Optional[str] | List[str] = None, - output_variable: Optional[str] | List[str] = None, - input_prefix: Optional[str] | List[str] = None, - output_prefix: Optional[str] | List[str] = None): - - if all(x is None for x in [input_variable, output_variable, input_prefix, output_prefix]): + def __init__( + self, + name: Optional[str] | List[str] = None, + input_variable: Optional[str] | List[str] = None, + output_variable: Optional[str] | List[str] = None, + input_prefix: Optional[str] | List[str] = None, + output_prefix: Optional[str] | List[str] = None, + ): + + if all( + x is None + for x in [input_variable, output_variable, input_prefix, output_prefix] + ): warnings.warn( - 'No input/output information set for PipelineOp...this is likely an error', - stacklevel=2 + "No input/output information set for PipelineOp...this is likely an error", + stacklevel=2, ) - - self.name = name or 'PipelineOp' + + self.name = name or "PipelineOp" self.input_variable = input_variable self.output_variable = output_variable self.input_prefix = input_prefix @@ -51,7 +56,7 @@ def __init__(self, self.output: Dict[str, xr.DataArray] = {} # variables to exclude when constructing attrs dict for xarray - self._banned_from_attrs = ['output', '_banned_from_attrs'] + self._banned_from_attrs = ["output", "_banned_from_attrs"] ## PipelineContext try: @@ -69,7 +74,10 @@ def __init__(self, # Iterate through all frames in the stack. for frame_info in stack: # Look for __init__ functions where 'self' is our instance. - if frame_info.function == '__init__' and frame_info.frame.f_locals.get('self') is self: + if ( + frame_info.function == "__init__" + and frame_info.frame.f_locals.get("self") is self + ): valid_frames.append(frame_info) if valid_frames: # Choose the last __init__ call in the inheritance chain. @@ -79,7 +87,7 @@ def __init__(self, # Fallback: use the immediate caller if nothing was found. final_frame = inspect.currentframe().f_back args_info = inspect.getargvalues(final_frame) - + # Build _stored_args by checking JSON serializability of each constructor argument. stored_args = {} for arg in args_info.args: @@ -94,26 +102,30 @@ def __init__(self, ) stored_args[arg] = value self._stored_args = stored_args - + def __getattribute__(self, name): - # Avoid recursion when accessing _stored_args. - if name == '_stored_args': + if name == "_stored_args": + try: + return object.__getattribute__(self, name) + except AttributeError: + return {} + try: + stored_args = object.__getattribute__(self, "_stored_args") + except AttributeError: return object.__getattribute__(self, name) - - stored_args = object.__getattribute__(self, "_stored_args") if name in stored_args: return stored_args[name] return object.__getattribute__(self, name) - + def __setattr__(self, name, value): if name == "_stored_args": return object.__setattr__(self, name, value) - + try: stored_args = object.__getattribute__(self, "_stored_args") except AttributeError: stored_args = None - + if stored_args is not None and name in stored_args: try: json.dumps(value) @@ -125,7 +137,7 @@ def __setattr__(self, name, value): stored_args[name] = value else: object.__setattr__(self, name, value) - + def to_json(self): """ Serializes the fully qualified class name and the constructor arguments @@ -134,10 +146,7 @@ def to_json(self): cls = self.__class__ module = cls.__module__ qualname = cls.__qualname__ - data = { - "class": f"{module}.{qualname}", - "args": self._stored_args - } + data = {"class": f"{module}.{qualname}", "args": self._stored_args} return data @classmethod @@ -159,7 +168,7 @@ def calculate(self, dataset: xr.Dataset) -> Self: pass def __repr__(self) -> str: - return f'' + return f"" def copy(self) -> Self: return copy.deepcopy(self) @@ -167,7 +176,7 @@ def copy(self) -> Self: def _prefix_output(self, variable_name: str) -> str: prefixed_variable = copy.deepcopy(variable_name) if self.output_prefix is not None: - prefixed_variable = f'{self.output_prefix}_{prefixed_variable}' + prefixed_variable = f"{self.output_prefix}_{prefixed_variable}" return prefixed_variable def _get_attrs(self) -> Dict: @@ -178,7 +187,7 @@ def _get_attrs(self) -> Dict: except KeyError: pass - #sanitize + # sanitize for key in output_dict.keys(): output_dict[key] = str(output_dict[key]) # if output_dict[key] is None: @@ -190,16 +199,20 @@ def _get_attrs(self) -> Dict: def _get_variable(self, dataset: xr.Dataset) -> xr.DataArray: if self.input_variable is None and self.input_prefix is None: - raise ValueError(( - """Can't get variable for {self.name} without input_variable """ - """or input_prefix specified in constructor """ - )) + raise ValueError( + ( + """Can't get variable for {self.name} without input_variable """ + """or input_prefix specified in constructor """ + ) + ) if self.input_variable is not None and self.input_prefix is not None: - raise ValueError(( - """Both input_variable and input_prefix were specified in constructor. """ - """Only one should be specified to avoid ambiguous operation""" - )) + raise ValueError( + ( + """Both input_variable and input_prefix were specified in constructor. """ + """Only one should be specified to avoid ambiguous operation""" + ) + ) if self.input_variable is not None: output = dataset[self.input_variable].copy() @@ -229,10 +242,12 @@ def add_to_dataset(self, dataset, copy_dataset=True): value.attrs.update(self._get_attrs()) dataset1[name] = value else: - raise ValueError(( - f"""Items in output dictionary of PipelineOp {self.name} must be xr.Dataset or xr.DataArray """ - f"""Found variable named {name} of type {type(value)}.""" - )) + raise ValueError( + ( + f"""Items in output dictionary of PipelineOp {self.name} must be xr.Dataset or xr.DataArray """ + f"""Found variable named {name} of type {type(value)}.""" + ) + ) return dataset1 def add_to_tiled(self, tiled_data): @@ -242,20 +257,20 @@ def add_to_tiled(self, tiled_data): # for name, dataarray in self.output.items(): # tiled_data.add_array(name, value.values) - def plot(self,**mpl_kwargs) -> plt.Figure: + def plot(self, **mpl_kwargs) -> plt.Figure: n = len(self.output) - if n>0: - fig, axes = plt.subplots(n,1,figsize=(8,n*4)) - if n>1: + if n > 0: + fig, axes = plt.subplots(n, 1, figsize=(8, n * 4)) + if n > 1: axes = list(axes.flatten()) else: axes = [axes] - for i,(name,data) in enumerate(self.output.items()): - if 'sample' in data.dims: - data = data.plot(hue='sample',ax=axes[i],**mpl_kwargs) + for i, (name, data) in enumerate(self.output.items()): + if "sample" in data.dims: + data = data.plot(hue="sample", ax=axes[i], **mpl_kwargs) else: - data.plot(ax=axes[i],**mpl_kwargs) + data.plot(ax=axes[i], **mpl_kwargs) axes[i].set(title=name) return fig else: diff --git a/AFL/double_agent/data/__init__.py b/AFL/double_agent/data/__init__.py index 79fae98..e4853e8 100644 --- a/AFL/double_agent/data/__init__.py +++ b/AFL/double_agent/data/__init__.py @@ -10,11 +10,12 @@ import xarray as xr + # Get the path to the data directory def get_data_dir() -> pathlib.Path: """ Get the path to the data directory. - + Returns ------- pathlib.Path @@ -23,16 +24,17 @@ def get_data_dir() -> pathlib.Path: # The data directory is now located in AFL/double_agent/data module_dir = pathlib.Path(__file__).parent data_dir = module_dir - + if not data_dir.exists(): warnings.warn(f"Data directory not found at {data_dir}") - + return data_dir + def list_datasets() -> list[str]: """ List all available datasets. - + Returns ------- list @@ -42,23 +44,24 @@ def list_datasets() -> list[str]: if not data_dir.exists(): warnings.warn(f"Data directory not found at {data_dir}") return [] - + return [f.stem for f in data_dir.glob("*.nc")] + def load_dataset(name: str) -> xr.Dataset: """ Load a dataset by name. - + Parameters ---------- name : str Name of the dataset to load. - + Returns ------- xarray.Dataset The loaded dataset. - + Raises ------ FileNotFoundError @@ -66,21 +69,22 @@ def load_dataset(name: str) -> xr.Dataset: """ data_dir = get_data_dir() file_path = data_dir / f"{name}.nc" - + if not file_path.exists(): raise FileNotFoundError( f"Dataset '{name}' not found at {file_path}. " f"Data directory: {data_dir}. " f"Available datasets: {list_datasets()}" ) - + return xr.open_dataset(file_path) + # Define specific dataset loaders def example_dataset1() -> xr.Dataset: """ Load the example dataset. - + Returns ------- xarray.Dataset @@ -88,5 +92,6 @@ def example_dataset1() -> xr.Dataset: """ return load_dataset("example_dataset") + # Add all datasets as module-level variables -__all__ = ["load_dataset", "list_datasets", "example_dataset1"] \ No newline at end of file +__all__ = ["load_dataset", "list_datasets", "example_dataset1"] diff --git a/docs/source/tutorials/index.rst b/docs/source/tutorials/index.rst index a19c97d..bce27da 100644 --- a/docs/source/tutorials/index.rst +++ b/docs/source/tutorials/index.rst @@ -9,5 +9,6 @@ Step-by-step guides for beginners to use AFL-agent installation quickstart building_pipelines + interactive using_datasets - interactive \ No newline at end of file + using_prefab \ No newline at end of file diff --git a/docs/source/tutorials/using_prefab.ipynb b/docs/source/tutorials/using_prefab.ipynb new file mode 100644 index 0000000..ad7d184 --- /dev/null +++ b/docs/source/tutorials/using_prefab.ipynb @@ -0,0 +1,1502 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "341bc47b", + "metadata": {}, + "source": [ + "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/usnistgov/AFL-agent/blob/main/docs/source/tutorials/using_prefab.ipynb)\n", + "\n", + "# Using Prefabricated Pipelines\n" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "94aae7f7", + "metadata": {}, + "outputs": [], + "source": [ + "%load_ext autoreload\n", + "%autoreload 2" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "df5b7fd4", + "metadata": {}, + "outputs": [], + "source": [ + "# Import required libraries\n", + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "from AFL.double_agent import *\n", + "from AFL.double_agent.data import example_dataset1\n", + "from AFL.double_agent.prefab import load_prefab, list_prefabs, combine_prefabs" + ] + }, + { + "cell_type": "markdown", + "id": "573d1b1d", + "metadata": {}, + "source": [ + "Introduction\n", + "-----------\n", + "\n", + "Prefabricated pipelines (prefabs) are pre-configured pipelines that can be easily loaded and used in your projects. \n", + "This tutorial will guide you through the process of loading and using prefabricated pipelines from the ``AFL.double_agent.prefab`` module.\n", + "\n", + "Prefabricated pipelines are particularly useful when:\n", + "\n", + "* You have common processing steps that you use frequently\n", + "* You want to share pipeline configurations with colleagues\n", + "* You want to create building blocks that can be combined into more complex pipelines\n", + "\n", + "In this tutorial, we'll:\n", + "\n", + "1. Load an example dataset\n", + "2. Load a prefabricated pipeline \n", + "3. Inspect the pipeline\n", + "4. Customize the pipeline to work with our dataset\n", + "5. Execute the pipeline and analyze the results\n", + "\n", + "Let's get started!\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "id": "3b97422d", + "metadata": {}, + "source": [ + "## Google Colab Setup\n", + "\n", + "Only uncomment and run the next cell if you are running this notebook in Google Colab or if don't already have the AFL-agent package installed." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "26dfcff9", + "metadata": {}, + "outputs": [], + "source": [ + "# !pip install git+https://github.com/usnistgov/AFL-agent.git" + ] + }, + { + "cell_type": "markdown", + "id": "34e6a733", + "metadata": {}, + "source": [ + "\n", + "## Loading an Example Dataset\n", + "\n", + "First, let's load an example dataset from the ``AFL.double_agent.data`` module:\n" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "76b65e22", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
<xarray.Dataset> Size: 164kB\n",
+       "Dimensions:              (sample: 100, component: 2, x: 150, grid: 2500)\n",
+       "Coordinates:\n",
+       "  * component            (component) <U1 8B 'A' 'B'\n",
+       "  * x                    (x) float64 1kB 0.001 0.001047 0.001097 ... 0.9547 1.0\n",
+       "Dimensions without coordinates: sample, grid\n",
+       "Data variables:\n",
+       "    composition          (sample, component) float64 2kB ...\n",
+       "    ground_truth_labels  (sample) int64 800B ...\n",
+       "    measurement          (sample, x) float64 120kB ...\n",
+       "    composition_grid     (grid, component) float64 40kB ...
" + ], + "text/plain": [ + " Size: 164kB\n", + "Dimensions: (sample: 100, component: 2, x: 150, grid: 2500)\n", + "Coordinates:\n", + " * component (component) output_variable\n", + "---------- -----------------------------------\n", + "0 ) CartesianGridGenerator ---> composition_grid\n", + "1 ) composition_grid ---> normalized_composition_grid\n", + "2 ) composition ---> normalized_composition\n", + "3 ) measurement ---> measurement_derivative0\n", + "4 ) measurement ---> measurement_derivative1\n", + "5 ) measurement ---> measurement_derivative2\n", + "\n", + "Input Variables\n", + "---------------\n", + "0) CartesianGridGenerator\n", + "1) composition\n", + "2) measurement\n", + "\n", + "Output Variables\n", + "----------------\n", + "0) normalized_composition_grid\n", + "1) normalized_composition\n", + "2) measurement_derivative0\n", + "3) measurement_derivative1\n", + "4) measurement_derivative2\n" + ] + } + ], + "source": [ + "# Load the \"preprocess\" prefabricated pipeline\n", + "pipeline = load_prefab(\"preprocess\")\n", + "pipeline.print()" + ] + }, + { + "cell_type": "markdown", + "id": "0cc4a9dd", + "metadata": {}, + "source": [ + "## Inspecting the Pipeline Structure\n", + "\n", + "To better understand the pipeline we've loaded, we can visualize it using the ``.draw()`` method:" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "a548e17f", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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508227PngD9zT/IOi08qYHHxCWb6CMPuHVtcW/QzKnYZavlKV3HtrHhCDbvnrLr20EMP2dtvv20FCxa0aLV161YrXLiwr21QPL5jx45cOU6hfSma7K8frt+WnGvvMwCI5vOqd90+FGqn2utXMAPgENbM6Kb1tddecyO5+gid4ly6dKl16dLFypUr50Z7GzRoYK+88so+P+N///uf+56mSEuWLGnHHHOMvfnmmwfM5f/oo4+sTZs2VrFiRfeza9asaQ8++KAbXQ516qmnuhELzWS0bNnS/Y5KlSrZ448/blMXb0g7SW77+yfbtXqhFT+p/T6BjKdg9aZWsOYx+6yL2bHoT1s79llbPLSjLX2m837XzOjmesP4t23JM51t0aCLbcWb91ry6n3zbLdM+cx2b1lnJc+4zgUyonaqvaJj0aFDBzv22PQpb1k53hq10b9/99137eGHH3ZpawUKFLDTTz/d/vnnn33a8uuvv9pZZ51lxYsXd8euRYsWNn78+HTPuf/++93P1DG+/PLL3WvopcBNmzbN9YkaNWq431O+fHnXxrVr16b795qVkerVq6f1Je/1TklJca+tXmP9XZq56dWrl+3cuTNdO/T4ueeea2PHjnV9SEHMsGHD3HFRWp7XV/Q7brzxRktO3ntDP2/ePLvkkkusVKlS7m884YQT7NNPP93vcevfv7/rQ0WLFnWzkhs3brTJ81bZqnHDXB/QzMeaT5+y1JRd6X6G+sO6cc/Zlr++taUv3GALB15oy4ffZjsWTd/nuCevmGsr3+1ni564xP28lW/1sp1L/073nNTdKbbhpzdt6bDr3M9a/FQHW/FGD9s+f8p+18zo/1N37bDJX324z3t2f2tmlL6gvqRjp2N4880324YNG7L8PgMQLN45ffbs2XbFFVe48/9hhx1mffr0cdexxYsX2/nnn2/FihVz5/TBgwen+/c6N/fr189q1arlzhtVqlSxHj167HPOHj58uJ122mlWtmxZ9zylrD/33HNp3/eu0TuXz7GV7/SxxUMut0WDLrIlz13jzrGeHQun7b0WL5yW7ufr+qvHdT32aH2qzqm71i9PO8eu+WSQ+15q6h7b9NtHtuylm/aeU4deYWu/eNoNMGbMplDmhH7f8le7uzYtevEmG/fVN+77H3zwgTVq1Mhd844++mibMmXf2aW///7bXT903dHzdM36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liUXOixi59XU9Uus9o7Z9uWrgyPaXgC5g2AmEzokUxZvsBETFton05ZZyp5US4yPc58PxnuePmvzr04nVLMjq5Rg1+AYRV8CgMh45513rH379vbjjz9aoaoNInZenfzlaLv22mts8uTJdtRRR+XK3wIgcghmDmLd1mSbMG+tTVuywaYt2eg+b03evc/zCiclWOPKJaxJlRLWqFJxa1ajtJWiLj1C0JcAIDwpKSnWoEEDq1mzpn322WcRPa96P/uII46wMWPG5OrfBeDQEcxkkw7X2q3J9uU339mVV3Wx8T9+bzWqVbHShZMYMUdYfendUaPtttvvtBnT/7SSxQrTlwAgg1deecWuueYa+/33361p06YHPa9+9c331umqq+2nH76zmodXPeh51Zv1GT9+vJ144ok59FcAyAkxu89MuHQyLFMkv5UuEGcp65dZ+aJJ7mtuPhFuXyqZlOr6UqUSBehLAJDBzp07rX///tauXbsDBjLprtEFs3eNvuSSS6xJkybWu3dvFxABCA6CGQAAELVefPFFW7JkiT3wwAM59jvi4+PtwQcftO+++86+/vrrHPs9ACKPYAYAAESlrVu32kMPPWSdOnWyevXq5ejvOvfcc+2EE06wXr16MTsDBAjBDAAAiEpPP/20rVu3zvr165fjv0upaA8//LD99ttv9vHHH+f47wMQGQQzAAAg6mzcuNEee+wxu/baa6169eq58jtPO+0093Hfffe5fW0ARD+CGQAAEHUGDx5s27dvd4FFbtLszPTp0+3tt9/O1d8LIDwEMwAAIKqsXr3annzySevWrZtVrFgxV3+31s20bdvWpbbt2rUrV383gOwjmAEAAFFF6WVaw9KzZ09ffr8qm/3zzz/22muv+fL7AWQdwQwAAIgaS5cutWeeecZuv/12K1OmjC9t0J4zl112mdvfZseOHb60AUDWEMwAAICooVLMhQoVsjvuuMPXdmhfm+XLl9uwYcN8bQeAAyOYAQAAUWHevHn20ksvufSy4sWL+9qW2rVrW+fOnW3AgAFuvxsA0YlgBgAARAWldSm1TAv/o0Hfvn1t/fr1NnToUL+bAmA/CGYAAIDvZsyYYSNGjHClmJVmFg2qVatmXbt2tccff9w2bNjgd3MAZIJgBgAARMUsSNWqVe26666zaNKrVy/buXOnDRo0yO+mAMgEwQwAAPDV77//bqNGjXJ7uyQlJVk0KV++vN1666321FNP2apVq/xuDoAMCGYAAICvlFpWp04d69Spk0WjHj16WEJCgj3yyCN+NwVABgQzAADANz/99JN98cUXrhRyYmKiRaNSpUrZXXfdZc8995wtWbLE7+YACEEwAwAAfJGamurWpGiTynbt2lk06969uxUtWtQefPBBv5sCIATBDAAA8MW4cePsxx9/dBtlxsdH9y2JApl7773XXn75Zfvnn3/8bg6Af0X3mQMAAOTZWRmtlWnWrJm1adPGguDGG2+0cuXK2f333+93UwD8i2AGAADkug8//NAmTZpkDz/8sMXFxVkQFCxY0Pr06WNvvvmmTZ8+3e/mACCYAQAAuW337t0uKDj99NOtZcuWFiRdunSx6tWru/YD8B/BDAAAyFVvvfWW/fXXX25WJmi0D47SzDSz9Ntvv/ndHCDmEcwAAIBcs2vXLrc55nnnnWfHH3+8BdHll19u9evXd2t+APiLYAYAAOSa4cOH2/z58wNd4lgbaGpfHFVj+/777/1uDhDTCGYAAECu2LFjhwsC2rdvb40bN7Ygu+iii+zoo4+23r17u8psAPxBMAMAAHLFc889ZytWrLD+/ftb0KkCm/bHGT9+vH3xxRd+NweIWQQzAAAgx23evNkeeeQRu+qqq+yII46wvKB169bWvHlzNzuzZ88ev5sDxCSCGQAAkOOGDBliGzdutL59+1peodmZAQMG2JQpU+yDDz7wuzlATCKYAQAAOWr9+vU2aNAg69q1q1WtWtXykpNPPtnN0ChI0/45AHIXwQwAAMhRAwcOdCWZe/XqZXmR1s7MnDnTRo4c6XdTgJhDMAMAAHKMFvwrxey2226zcuXKWV50zDHHuOpm2j8nOTnZ7+YAMYVgBgAA5Bgt+s+XL5/dfffdlpep5PTChQvt5Zdf9rspQEwhmAEAADli0aJF9vzzz9tdd91lJUuWtLysQYMG1rFjR7cZ6Pbt2/1uDhAzCGYAAECO0I19sWLFXIpZLLj//vtt9erV9swzz/jdFCBmEMwAAICImzNnjg0fPtwt+i9atKjFgpo1a9o111xjjz76qG3atMnv5gAxgWAGAABEnBbDly9f3m688UaLJffdd59t2bLFnnrqKb+bAsQEghkAABBR06ZNs7ffftv69OljBQoUsFhSuXJlu/nmm92+OmvXrvW7OUCeRzADAAAiSkFM9erVrUuXLhaL7rnnHktNTbXHH3/c76YAeR7BDAAAiJhff/3VPv74Y+vfv78ryRyLDjvsMOvevbv973//s+XLl/vdHCBPI5gBAAARXTNSv35969Chg8WyO++806XYPfzww343BcjTCGYAAEBEfPvtt/bVV1/ZQw89ZAkJCRbLSpQoYT169LAXXnjBFixY4HdzgDyLYAYAABwyrRHp3bu3HXPMMXbBBRf43ZyocMstt1ipUqXsgQce8LspQJ5FMAMAAA7ZZ599ZhMmTHCzMnFxcX43JyoULlzY7bPz2muv2d9//+13c4A8iWAGAAAckj179ri1MqeccoqdeeaZfjcnqtxwww1WqVIlt+8OgMgjmAEAAIfk/ffftz/++MMtdmdWJr38+fO7QObdd991xwhAZBHMAACAsKWkpFjfvn3trLPOsubNm/vdnKjUuXNnO+KII9zsFYDIIpgBAABhe+ONN2zWrFlurQwyl5iY6IoAfPrpp25dEYDIIZgBAABh2blzp91///128cUX29FHH+13c6LapZdeao0bN3YV3wBEDsEMAAAIy0svvWSLFi2i9HAWxMfH24MPPuj24vn666/9bg6QZxDMAACAbNu2bZtLLbviiiusfv36fjcnENq2bWvHH3+8K9esfXkAHDqCGQAAkG1PP/20rVmzxqWZIWtU6U0V3yZOnGiffPKJ380B8gSCGQAAkC0bN260xx57zK699lqrUaOG380JlNNPP91atmzpKptpfx4Ah4ZgJkzlypVzi/kKFSrkd1MAAMhVTz75pEszo9RweDQ78+eff9o777zjd1OAwCOYCVOTJk3cSahMmTJ+NwUAgFyj1LLBgwfbzTff7Ha2R/Y1a9bMzj33XLeZpvbpARA+ghkAAJBlSi+Te+65x++mBJoqm82ZM8dee+01v5sCBBrBDAAAyJJly5a5hf+33347mQmH6Mgjj7TLLrvM+vfv7/brARAeghkAAJDltR4FCxa0O++80++m5AkKZJYuXWrDhg3zuylAYBHMAACAg5o/f7698MIL1rNnTytevLjfzckT6tSpY507d3ZB4tatW/1uDhBIBDMAACBLswilS5e2bt26+d2UPEVFANavX29Dhw71uylAIBHMAACAA5o5c6aNGDHCevfubYULF/a7OXlKtWrV7IYbbrDHH3/cNmzY4HdzgMAhmDlEGk3RTr6//fab+38AAPKavn37WuXKle3666/3uyl5koJEFQFQyWsA2UMwcwi5w+ecc46r5nLCCSfY8ccf7/5fjy1cuNDv5gEAEBFTpkyx999/36VD5c+f3+/m5Enly5e3W265xW1GumrVKr+bAwQKwUwYVq5cac2bN7fp06fbgAEDbPTo0e7jkUcecY+deOKJ7jkAAATdfffdZ7Vr17Yrr7zS76bkaT169LCEhAR79NFH/W4KECiJfjcgiFR1pFSpUi69TCUqQ91666127LHH2kMPPWT/+9//fGsjAACHavz48fbZZ5/Z22+/bYmJ3DLkJBVXUMlrDZLecccdLq0PwMExMxOGMWPGuKouGQMZKVCggNvVVyd/AACCKjU11a3laNKkiV1yySV+NycmdO/e3YoUKeLuIwBkDcFMGJYvX26NGzfe7/cbNmzoNsECACCovvrqK/v+++/djXV8PLcLuaFYsWJ277332iuvvGJz5871uzlAIHB2CsNhhx1mKSkp+/3+rl27rFy5crnaJgAAIjkr06tXL1fg5txzz/W7OTHlpptusrJly9r999/vd1OAQCCYCcPRRx9t48aN2+/3v/jiCzctDwBAEH300Uc2adIkt0Y0Li7O7+bEFKWwq+jCyJEj7a+//vK7OUDUI5gJgxbmDRs2zDZu3LjP9zZt2mQvvviiy3sFACBodu/ebX369LHTTjvNfSD3XXPNNXb44Ye71wHAgVGaJAwnn3yyq+zy9ddfu1ka7d4bmu86Y8YMX9sHAEC43nnnHbfNwIQJE/xuSsxKSkpyaWadO3d2M2THHHOM300CohYzM2EYMmSISyO7/PLLrW7dum6RpAwdOtRteAUAQBBpzWffvn2tbdu2br0M/NOxY0erV6+eSzkDsH8EM2EYOHCgPfXUU7Zjxw67+eab0za4UoAzfPhwv5sHAEBYXn31VVdFi9LA/tMGmnodxo4daz/88IPfzQGiFsFMGDZs2OBGreTSSy+1v//+2/1/9erVbd68eT63DgCA7NMA3QMPPGDt27eniE2UuOiii6xp06Zuvx9VmAOwL4KZMJxyyin2008/uf8vVaqUW/QvCmT0NQAAQfP888+7fdS0KTSigyrJPfTQQ+6eQzM0APZFAYAw81jvueceW7hwoVWqVMntOTNq1ChXdcSbsQEAICi2bNliAwYMcAvOa9eu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bdu2tmHDBktKSrIffvjBOnXqZAsXLvS7qQCiiC7dSifbsWOH27SZ8rv/OfbYY6179+4ug8IbJNI6186dO9sFF1xgPXv2dClYzz33nN9NBRABzD+GOepzIP369XM1/gcOHOj+H9ifXbt2WdGiRdO+/uWXX9xu3QpkpHr16rZy5UofWwggmilLoHXr1tasWbOYTi0LNXfuXGvcuHHa1z/++KO7Jj/yyCPu3Proo4+6QaJY9+STT9onn3xiF154oZ155plWp04d27NnDwUDEDgEM2H46KOPDjhapgBGxQD0PIIZHIgq4P32229pG7B+/vnn1qJFi7TvK5BRWgQAhNJMjNZpPvbYY3bjjTcSyIRgkOjAFLDce++9bsD16quvtrfeesveeecdlyVAP0IQEcyEYfLkyQd9jm5As/I8xDYVj7j11ltt8eLFNnPmTLdHUWjqg9LOlA4BABlpTd31119P1bIMGCSyAw64KjXxm2++cRuqag2wyjfrWtSjRw8bPHgwszMIHIIZwEcaHVu2bJlLe9DeEC+//HLa+hlp0KCBW6wKAKE0in7DDTe46lxXXnmlK0iD9INES5YssRkzZmQ6SHTkkUdarNBWEv/73//cvjPaPqJQoUIuWNHaTFEwrKBG/ejBBx903weChNA7DFOnTrWjjz7aihUrZmeddZatWrXKPf7tt9/apEmT/G4eAkQLd1944QXXh+bPn+8uJqJKO0qFOPfcc10uPACE0sxCpUqV3LlDI+oTJkzwu0lRNUikQipaI6OKo5kNEunmPZYCXwV1q1evdl9r5uX88893QZ7WEomuNzVq1LBPP/3U59YC2UcwEwZN6x922GFupGf9+vXWu3dv97imanv16uV38xAgY8aMcYsuFdRopMz7KFu2rC1atCjtawAIpQXummEYO3asW6N58sknu+pd06dPt1in82m3bt3s+eeft++++y5tkMgTK4NEXrFazdotWLAgbY8dXVMqV67s9qD5559/3GPFixd35ax1PQKChtLMYVA60O+//25169Z1F5JbbrnFZs+ebXPmzHEbaXqjH8DB6MLRqlUrO/3009MtvNRFR2VEP/zwQ/f1eeed52MrAUSbtWvXuk0gNfAhqkqlNRAKZnRTqtkI3dTHoiFDhtgdd9zhUqpUKEHH5owzzrChQ4e6Y3b77bdbrJXw1pohrb/UMRCtmTnn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6XdzAORx9evXt06dOrn9rLZt2+Z3c5BFBDMAgKgdJS1evLjddtttfjcFQIzo16+frVmzxp555hm/m4IsIpgBAESd2bNn26uvvmq9evWyIkWK+N0cADGiRo0adu2119qjjz7qysEj+hHMAACicnS0QoUK1rVrV7+bAiDG3HfffS7N7IknnvC7KcgCghkAQFSZNm2avf32227PhwIFCvjdHAAxplKlSnbzzTe7YGbt2rV+NwcHQTADAIgqffr0sZo1a9pVV13ld1MAxKh77rnHUlNT7bHHHvO7KTgIghkAQNT49ddf7eOPP3Z7PagkMwD4oUyZMnb77bfb//73P1u2bJnfzcEBEMwAAKJG7969rWHDhta+fXu/mwIgxt15551WsGBBe/jhh/1uCg6AYAYAEBW+/fZb+/rrr90eDwkJCX43B0CMU2n4nj172osvvmgLFizwuznYD4IZAIDvlJuuWZljjz3Wzj//fL+bAwBOt27drFSpUi71FdGJYAYA4LtPP/3UJkyY4NI54uLi/G4OADiFCxd2pZpff/11mzlzpt/NQSYIZgAAvtqzZ4+7WWjRooWdccYZfjcHANK57rrrrHLlym7/K0QfghkAgK/ef/99mzp1KrMyAKJS/vz5XSDz3nvv2ZQpU/xuDjIgmAEA+CYlJcXtK3POOefYSSed5HdzACBTV155pdWuXdvNIiO6EMwAAHwzYsQImz17tj300EN+NwUA9isxMdEeeOAB++yzz+znn3/2uzkIQTADAPDFzp07XYWgdu3a2VFHHeV3cwDggC655BJr0qSJ9erVy1VgRHQgmAEA+EJ7NyxevNiNdgJAtIuPj3ezyN9//7199dVXfjcH/yKYAQDkum3btrkF/506dbJ69er53RwAyJI2bdrYCSec4PbFYnYmOhDMAABy3dNPP21r166l1CmAQFHFRQ3E/Pbbb/bxxx/73RwQzAAActvGjRvt0UcftWuvvdaqV6/ud3MAIFtOO+00O/30011ls927d/vdnJhHMAMAyFVPPPGEbd++nRKnAAJLszPTp0+3d955x++mxDyCGQBArlmzZo0LZrp162YVK1b0uzkAEJbjjz/e2rZt61Jld+3a5XdzYhrBDAAg1yi9TDnnPXv29LspAHBIHnzwQfvnn3/s1Vdf9bspMY1gBgCQK5YtW2bPPPOM3XHHHVamTBm/mwMAh0R7zrRv396Vl9+xY4ffzYlZBDMAgFyh/RkKFSrkghkAyAu08e/y5ctt2LBhfjclZhHMAABy3Lx589wmmUovK1asmN/NAYCIqF27tnXu3NkGDBhgW7Zs8bs5MYlgBgCQK6OXSi3Twn8AyEv69u1rGzZssKFDh/rdlJgUl8r2pdmi3aq12Eud9u+//7ajjjrK8ufP72qOq0wfkBUpKSnWrl07W7lypavupD513HHHWXx8vF100UV29913+91EIGJmzpxpDRs2dBf6m2++2e/mIAau0drLSP2OazRyy6233mojRoyw+fPnW4kSJfxuTkwhmAljOnHOnDn7PH7BBRfY6NGjfWkTghnMqCzt6tWr9/meNhJUOg6QV1xyySVut+zZs2dbUlKS381BHlanTh3XzzI677zz7KOPPvKlTYgNK1assBo1arg1gVofiNxDmlk23X///Zk+3qdPn1xvC4IrMTHRbRioErWhNDNz7733+tYuIBIUuFx55ZX2+++/2+TJk+399993504CGfh1jVYaEJCTypcvb7fddps99dRTLuti3Lhxdtlll9mSJUv8blqex8xMNu3evduN/Ggxqw5dQkKCnX322fbJJ5/43TQEjHZAr1atWtrsjPqSbgBfeeUVv5sGHPJeMl5QXrZsWVfBTDPaCuKBnL5G161b1+bOnZt2jT7rrLNszJgxfjcNMWDdunVWpUoVl2amUvTywQcf2IUXXuh30/I0ZmaySSdG1RP3YkCdOLWwFciuggULutkZj/pU6NdAUGk3bC9wWbVqlS1YsMCuvvpq9xnISVyj4Zc//vjDOnToYNu2bUsLZLy0cuQsgpkwaNqwQoUK7v9PP/10a9q0qd9NQkBdd911VrRoUff/HTt2dPm2QNDp4p0xhfKNN96wG264wbc2IXZceumlbk2itGzZ0o4++mi/m4Q8TsHz+eef71LLMiKYyXkEM2GO/KhqhfTu3dvv5iDgszOqTy+9evXyuzlAROjivWfPnnRrwVTNbMiQIb62C7GBazRymwZvRo4c6Qa61f8yzlQjZxHMhBF9r9my0zrecKv9MOVvq3Xk8e5rlh4h3L7Uo/+j9uMfs6xwuar0JURtP128fpvNW73FfT5YP01OTnbpPZ5bbrnFJk2a5NYyALnRXy+//hZ3ja7dtBnnVeSK5s2b219//eUq52VnZiaccyzSYzXm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fd4262cL185ls2zlu/1s8ZOX2aLBF9uyl7vZpt8+Svec7Qumuv6p7y968jJb9f6DtmvN4nTPUX+dO6CN/Thpml1xxRVWvHhxO+yww6xPnz4uyFy8eLGdf/75VqxYMStfvrwNHjw43b/3jtM777xjvXr1cs/RcTjvvPPcv83ovffec+9BveZlypRxv1Pni1ArVqxwr23lypXda6gLm9qg116/a/bs2VauXDlLTEx0bb3yyivt2GOPdf9W/857nTRTGLpmRn1FqQu1atVyP1evlT4UFOn8MGjQIPc3h/Yh/Rydp7p27WoNGzZ0/65Bgwb2xRdf2KRJk6x169bu79Dfo/Ncly5dDponnFnOudqoPj137lw3Wq52dezYMe39qXQP/V695/S333DDDbZ+/fp0P1d/47nnnut+n/e+atSoUdrv/+CDD9zX3nlQ57ypizek66e71i621aMH2OKn2rt+uvzV7rZtzq/pfo933tqxZIat+/pFWzzkctfHVo16yHZv++/mTWvBdq1ZZDsXT087960YeY9lVWrKLlv31b8//4lLbNm7/W3CtNmZPld9SMdex8Z7jV555ZV0z/FeD93U33fffWnnpU2bNu3zWum6oddj27Zt+/yuDh06uH6+e/du9/VHH33k3vPe9U7nvwcffND69u2brr/qGqebM69/qn+rX+u1Du2v6ofevwvtr1WqVHHXSgXnoa+93qulS5d2Nwr6d3r/3XXXXenarBkZfV/nKq+/1qtXz0qUKGETJkxw71X6K/01Wvqr/r3uE3R+PeOMvbMOd999d+DOrxLaZ6O5v656/wHbsWF1YPqr933R+tmMMcQhp5kp3eO4446zDRs2uNGfunXrugOhk6karg5y4oknuv+/9dZbXad+7bXX3M2PnnPhhRem+3kaSVKnueeee+yff/6x//3vf+7NoTeCfpZutH/55RfXcXUzoTdkqO+//97daOl36UA8++yzLg9TI1W6ORHdYOtmdGdcfit2/MUWl5BoW6Z8bivevNfKd3zU8les456nQGbThPesSJMzLalibUvduc12rvjHklfOtYLVj8r0eJQ+905b+/lQy1+hthU58iz3WL6S5fd7/HRzuXH8W1bg8COtyFFnW8rapbZ5ymeWvHy2lb9ioGubZ+vmje5vueiii+zSSy91x0850XpDnX322Vl9yezee+91QVDbtm3dyWPq1Knus6LqUDp2ohOBd9Opk1WoJ5980gUfd955pz3//PMucNQbQKMrkydPtjPPPNPdMCo4UafVSeO6665zN5OReM0VuOiNpv6km91PPvnEbrrpJnfCuvnmm7N8THShHzFiRPrXZsMGF6zpJtej53Tu3NkdLwV76tdqw6JvulqFq4ZYYoly7nnb50+21aMfsXxlqljJFp1t947NtuazIZZYtLRll4LnVe/3t4TCpazoMedZQpGSLkjZPvc3K3bs+Xufs+APW/VuP0ssUd6KN7/cUncl2+bfP7EVb9ydrl2eb57pZRe2PM4effRRd1J46KGH3E28gkzd2Otv06CALjoKHDRtHOrhhx92Jyv1v1WrVrmLgy5CWsOi11L0einY0L/Xa7xy5UobMmSIjR8/3p34dWMlF198sXtP3nLLLe4Cop+n3H71Gbnsssvc5xo1aljt2rXda6D3gQIMBa/6+bpB0/ter72oz6lP/PTTT66/6bmzZs1ybdb7RSPUuljqXKX2eH3o9ttvt127drnjoAuZ/u3QoUPde07nE/UF9VO1XRdRXdDClZKS4vqRUn50g6ALgeg94h07ncfmz59vTz/9tDtmamtouofeL5pq179RoKifo/e13osKNr3joeOvc0a+DkPS/m3y6oUu+FWfLHZCO4vPV8C2/v2TrR71kB124b1WqM6J6dq7/sthFl+gsBVv3sF2b1zlgul14563wy7o6b5f6ozrbN2XwywuqYAVb7b3NUsovPc1zgqdN7f+9a0Vqt/CClSqZzsWTrOxT6RPeRH1I52HvMErBbi6adeAmi6kGdNkdCFUAKu+rAA3sxk+9bFnnnnGvRc08ObR+1vnFN0ceSPTem10Yda5QZ8146FzUrNmzdJ+lvqTfo/aqv6k10jXJl3w9Z7RDZ7XX/W6qC/qddMNna6jOh/9+eef7nXX+bRkyZLuZ+t36b2nAEX9VW1SCqYGHXQ8vFHtX3/de8OknxfaX71znN6n3nk9q+iv6dFfI9dfdc7XvYKOja6vOufqmOm6Hy4/+uvff/+dNjsXhP666r29C/9DSzRHa3/V7/b6S+/evdPuDw4qNYuuvPLK1Pj4+NTffvttn+/t2bMntXv37jpKqT/++GPa45s3b06tXr166uGHH566e/du99i3337rntewYcPU5OTktOd26NAhNS4uLvXss89O97ObNWuWWq1atXSP6d/rY9KkSWmPLVy4MLVAgQKpF154YdpjF1xwQWpSUlJqxa4vpVa7Z4z7qNTt9dS4pIKp+as0THssX9nqqQVrHpv2dWYfxU/q4H5n6GNx+QqkFm54+j7PLX3O3mNRqevL7uvKt45MtYTE1ALVj0qt2vPjtOeVatXVPa/0ObelPaZ26bFnXng57e/YuXNnavny5VMvvvjirL5cqStWrEhNTEx0xyDU/fff735+586dU/v16+f+/+STT3afmzdvnpqSkuKOYenSpd3z+/fv77532WWXua9XrVrljmmNGjXc49988417vFevXmmvyxdffJHud0biNd+2bds+f2Pr1q1dO0K1aNHCfXjmz5/vfvfw4cMzPU7qu+eee25qkSJFUv/666+0fluiRInU6667Lt1z/5q7MDUuf+HUIk1ah/SdGqkJRUqlVun+TtpjZS970P3OhGJlD9inQj+q9vgoNbF4OfdvqnR/O/33en6S7vfFFyqRWvm2t9Ieq9Dlf6kWF59auOFp+/TXIkeelbp68w7Xfr22lStXdsf80UcfTfu71q9fn1qwYEHXJzK+ZpUqVUrdtGlT2uPvvvuue3zIkCHua72eZcuWda/t9u3b0543ZswY97y+ffum/Q59PXDgwH1eA68fXn/99WmvX2hbQ1+/0LbqQ/1U5yWddz788EP33Iceeij1+eefd/8/fvz41Hbt2rmfM3369LTfqe+pH6vve31o6tSpaX04s/NcxmOjz6Ey62tqox6755570j1X7dXjI0eOTPe43jsZH9d7QY/9/PPPaY+NHTvWPaZjoXOfZ9iwYe7xch0GpPWFAtWapOY77PDUqneNTten8leql5pYsuI+560Chx+Zrs8VPfZ8179C+3i+MlXTnUOz+lHh6qF7+2XTNukeL1S/hXtcfcFzzTXXpFaoUCF1zZo16Y5R+/btU4sXL552TvBeD72OGc8TGV8rvd/VpzOeS71+/cMPPxzwnHPDDTe486rXX6VNmzapVatW3ee95fUH9TPvvVWrVq19rpMTJ05M63fqr2rjEUcckXrGGWe4/w9tj15vfXiqVKmSaX/VuUyP631Af6W/Rkt/HT16dFp/1Udm1+Yg9NcPPxsbyP569729o76/FipUKHXHjr33LF5/zYosp5l9+OGHLlLVNFxGiuw+++wzN3MTuuBQ0Zai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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Visualize the pipeline structure\n", + "pipeline.draw();" + ] + }, + { + "cell_type": "markdown", + "id": "a2a9c229", + "metadata": {}, + "source": [ + "## Generating Code for the Pipeline\n", + "\n", + "The ``print_code()`` method allows us to extract Python code that recreates the pipeline. This is particularly useful when we want to:\n", + "\n", + "1. Understand how the pipeline was built\n", + "2. Modify the pipeline to suit our needs\n", + "3. Create a new pipeline based on the existing one\n", + "\n", + "Now, let's reproduce the code from the Pipeline and modify it to work with our example dataset. You'll need to make the following changes:\n", + "\n", + "- Change the `dim` argument for the Savgol filters from \"q\" to \"x\" to match the example_dataset" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "id": "9f144895", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Pipeline code has been prepared in a new cell below.\n" + ] + } + ], + "source": [ + "# Generate code for the pipeline\n", + "pipeline.print_code()" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "id": "44e2dd7b", + "metadata": {}, + "outputs": [], + "source": [ + "with Pipeline(name = \"preprocess\") as p:\n", + " CartesianGrid(\n", + " output_variable=\"composition_grid\",\n", + " grid_spec={'A': {'min': 0.0, 'max': 10.0, 'steps': 50}, 'B': {'min': 0.0, 'max': 25.0, 'steps': 50}},\n", + " sample_dim=\"grid\",\n", + " component_dim=\"component\",\n", + " name=\"CartesianGridGenerator\",\n", + " )\n", + "\n", + " Standardize(\n", + " input_variable=\"composition_grid\",\n", + " output_variable=\"normalized_composition_grid\",\n", + " dim=\"grid\",\n", + " component_dim=\"component\",\n", + " scale_variable=None,\n", + " min_val={'A': 0.0, 'B': 0.0},\n", + " max_val={'A': 10.0, 'B': 25.0},\n", + " name=\"Standardize\",\n", + " )\n", + "\n", + " Standardize(\n", + " input_variable=\"composition\",\n", + " output_variable=\"normalized_composition\",\n", + " dim=\"sample\",\n", + " component_dim=\"component\",\n", + " scale_variable=None,\n", + " min_val={'A': 0.0, 'B': 0.0},\n", + " max_val={'A': 10.0, 'B': 25.0},\n", + " name=\"Standardize\",\n", + " )\n", + "\n", + " SavgolFilter(\n", + " input_variable=\"measurement\",\n", + " output_variable=\"measurement_derivative0\",\n", + " dim=\"x\",\n", + " xlo=None,\n", + " xhi=None,\n", + " xlo_isel=None,\n", + " xhi_isel=None,\n", + " pedestal=None,\n", + " npts=250,\n", + " derivative=0,\n", + " window_length=31,\n", + " polyorder=2,\n", + " apply_log_scale=True,\n", + " name=\"SavgolFilter\",\n", + " )\n", + "\n", + " SavgolFilter(\n", + " input_variable=\"measurement\",\n", + " output_variable=\"measurement_derivative1\",\n", + " dim=\"x\",\n", + " xlo=None,\n", + " xhi=None,\n", + " xlo_isel=None,\n", + " xhi_isel=None,\n", + " pedestal=None,\n", + " npts=250,\n", + " derivative=1,\n", + " window_length=31,\n", + " polyorder=2,\n", + " apply_log_scale=True,\n", + " name=\"SavgolFilter\",\n", + " )\n", + "\n", + " SavgolFilter(\n", + " input_variable=\"measurement\",\n", + " output_variable=\"measurement_derivative2\",\n", + " dim=\"x\",\n", + " xlo=None,\n", + " xhi=None,\n", + " xlo_isel=None,\n", + " xhi_isel=None,\n", + " pedestal=None,\n", + " npts=250,\n", + " derivative=2,\n", + " window_length=31,\n", + " polyorder=2,\n", + " apply_log_scale=True,\n", + " name=\"SavgolFilter\",\n", + " )\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "id": "ee1dff21", + "metadata": {}, + "source": [ + "## Running the Pipeline\n", + "\n", + "Now let's run our customized pipeline on the example dataset:" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "id": "56f7039b", + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "5702d4c0a57f497c96d12042889f7689", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + " 0%| | 0/6 [00:00\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
<xarray.Dataset> Size: 807kB\n",
+       "Dimensions:                      (sample: 100, component: 2, x: 150,\n",
+       "                                  grid: 2500, log_x: 250)\n",
+       "Coordinates:\n",
+       "  * component                    (component) <U1 8B 'A' 'B'\n",
+       "  * x                            (x) float64 1kB 0.001 0.001047 ... 0.9547 1.0\n",
+       "  * log_x                        (log_x) float64 2kB -3.0 -2.988 ... 0.0\n",
+       "Dimensions without coordinates: sample, grid\n",
+       "Data variables:\n",
+       "    composition                  (sample, component) float64 2kB ...\n",
+       "    ground_truth_labels          (sample) int64 800B ...\n",
+       "    measurement                  (sample, x) float64 120kB ...\n",
+       "    composition_grid             (grid, component) float64 40kB 0.0 0.0 ... 25.0\n",
+       "    normalized_composition_grid  (grid, component) float64 40kB 0.0 0.0 ... 1.0\n",
+       "    normalized_composition       (sample, component) float64 2kB 0.1935 ... 0...\n",
+       "    measurement_derivative0      (sample, log_x) float64 200kB 6.306 ... 0.3073\n",
+       "    measurement_derivative1      (sample, log_x) float64 200kB -3.828 ... -0....\n",
+       "    measurement_derivative2      (sample, log_x) float64 200kB -1.838 ... -0....
" + ], + "text/plain": [ + " Size: 807kB\n", + "Dimensions: (sample: 100, component: 2, x: 150,\n", + " grid: 2500, log_x: 250)\n", + "Coordinates:\n", + " * component (component) " + ] + }, + "execution_count": 40, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "fig,axes = plt.subplots(1,2,figsize=(8,3))\n", + "result.composition.to_dataset('component').plot.scatter(x='A',y='B',ax=axes[0])\n", + "result.normalized_composition.to_dataset('component').plot.scatter(x='A',y='B',ax=axes[1])" + ] + }, + { + "cell_type": "markdown", + "id": "9f66648d", + "metadata": {}, + "source": [ + "We can see that the relative positions of the compositions are unchanged, we simply renormalized the bounds of the data. " + ] + }, + { + "cell_type": "markdown", + "id": "2b004cfe", + "metadata": {}, + "source": [ + "## Combining Multiple Prefabs\n", + "\n", + "One of the powerful features of prefabricated pipelines is the ability to combine multiple prefabs into a single pipeline:" + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "id": "72a70d7a", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAzMAAAMzCAYAAACSq0y2AAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjAsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvlHJYcgAAAAlwSFlzAAAPYQAAD2EBqD+naQAA5lxJREFUeJzs3Qd0VMUXx/FLQgu9SgcBFaSqgF3Aig0b1r9iQVFUxAIWVEDAgiii2HvvBQv2ithBpdhQ6dJ7hxDI/3wHJ25CCMlmk7dv9/c5JweySTYv+2bfmztz506JzMzMTBMREREREQmZlKAPQEREREREJBoKZkREREREJJQUzIiIiIiISCgpmBERERERkVBSMCMiIiIiIqGkYEZEREREREJJwYyIiIiIiISSghkREREREQklBTMiIiIiIhJKCmZERERERCSUFMyIiIiIiEgoKZgREREREZFQUjAjIiIiIiKhpGBGRERERERCScGMiIiIiIiEkoIZEREREREJJQUzIiIiIiISSgpmREREREQklBTMiIiIiIhIKCmYERERERGRUFIwIyIiIiIioaRgRkREREREQknBjIiIiIiIhJKCGRERERERCSUFMyIiIiIiEkoKZkREREREJJQUzIiIiIiISCgpmBERERERkVBSMCMiIiIiIqGkYEZEREREREJJwYyIiIiIiISSghkREREREQklBTMiIiIiIhJKCmZERERERCSUFMyIiIiIiEgoKZgREREREZFQUjAjIiIiIiKhpGBGRERERERCScGMiIiIiIiEkoIZEREREREJJQUzIiIiIiISSgpmREREREQklBTMiIiIiIhIKCmYERERERGRUFIwIyIiIiIioaRgRkREREREQknBjIiIiIiIhJKCGRERERERCSUFMyIiIiIiEkoKZkREREREJJQUzIiIiIiISCgpmBERERERkVBSMCMiIiIiIqGkYEZEREREREKpZNAHEDaZmZm2dG26rd+02TZlbLFSJVMsrVSqVS9f2kqUKBH04UmM6XyLiMQXXZdFJJKCmR1Ytjbdvpm2xKbMXWmT5qxw/65N37zN95UvnWqt61W2tg2quH/3b1rDqpUvHcgxS/R0vkVE4ouuyyKSlxKZDHFINrwkP81eYc9+N9PGTJ5vGVsyrWRKCffvjvjv49+ubepa9/0a2Z4Nqmi0KI7pfIuIxBddl0Uk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eY9dsvW6POosW/rBfW4QMWfGBNkR/L75T13hjmn2o5fYR5985r7+xhtvWOvWrd19rV27dvbzz9vOLv3xxx8uc6VatWru++jbvP3229m+x1/Xua9yL+QcMBB44okn2uLFi7O+j4yFX3/91WVk+Hsk13URicHMDBenvffe2y688EL3OUEFFi5c6DqSvOF69+7t3qDvv/++W+uxatUqtzYCjz76qPXp08e94S+//HI3kk4HmE40HePt4QJAihtvfv797LPPbODAge6577jjjmzfu3z5ctchP+mkk1wn+LXXXrNrr73WGpwxxFIa7eW+Z93fP7h/y7cs+MWBDnBKWiUXCGVuyn4hj7Ry3HO28puXXUCU1qS9bVw4zRa9PMB1eiOt//sHK1GyjJXbbf9sjzMixE0mtxSj/L7e3rBhw1xnv1+/fq6zT6f2zDPPdK+7x2t61FFHuQs1Ny2+39+Yxo0b5857pFNOOcV23XVXt47KZyl+/PHHNn36dDvvvPPcDZGL8SOPPOL+/e6772z+/Pn23HPPuUCFQJTnIJXqhx9+cBd0/q62bdu6dtG8eXPXaee4Xn31VZs1a1a24wXPS/uhw87zEeT06tXLHfv82dPdDBtBx9opn1jJyrWsyoFnZPv5DXN+sbW/j7OK7btaidRStvqn92zRK4Os9jkjrHTNrelvBKALnr/WUsqUs0r7dLMSqSVtzc/vu+C09pnDrEzdZu77CGRWffuqVWh7hJWuu5tlblxnGxf8bekLp1la4z1zbSPVj+1rS98fZWXq7GY1Ohxtt53Y2nUW8uqQDB482A477DC7+OKLberUqa6jMH78eHdzLFWq1A7fB9yQOc8iknxOO+0023333d094d1333Uz/3S+H374YXetv/322+3555939woG0Eht3rJlix133HH21VdfuXs/Pz9lyhQbOXKkC45Ihfa4HnHd5vtLlixp77zzjl1yySXuOfiX+xoZEdwLU8pVtkr7nmwpZcu7dO/1U7+J+u8i24K08TL1W1jVg3tYiVJl3OPLPrjP1kz51Cq0PswqtutqGSsX2uofx7jrcu2z7nDXc49giCCowh5HWvmWB9uqH96wsff2s+f2qGQ33HCDO37cdttt7prK9Zd7jb8XHXDAAW7Q6LrrrnP3MwYRWV/8+uuvu2Al0mWXXeYGArnXMmB19913u3v5yy+/7L7O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UiSYVenVq5fbzPKuu+4q8M8TjFBKmWpmBVGpUiVr2bLlDoMZkP5G0QDW84hI+CiYERERkSLx4osv2pgxY+yhhx6yqlWrFjgQ8sFMNPi5/AQzpUuXdlXN3nvvPfviiy+i+l0iEhwFMyIiIhJzixYtsj59+thpp51mxx9/fIF/fvr06bZkyZICr5fx+LlffvnFbbi5I6eccopLTbv22mtdECUi4aFgRkRERGLusssuc+tW7r333qh+3s+q7L333lEHM1QzmzBhwg6/l+McPny4q4D22muvRfX7RCQYCmZEREQkpkaPHm2vvPKKK3tcs2bNqIMZFv5Tzjkau+++u1vg//333+fr+zt37mxHHXWUXX/99bZp06aofqeIFD8FMyIiIhIzy5Yts0suucSOO+44O/3006N+HoKQaFPMkJqa6mZ18rNuxhs2bJhNmzbNHn300ah/r4gULwUzIiIiEjNXXXWVrV+/3h588EGXvhUNfv7nn38uVDADfp5gJr/rYNq0aWNnn322DR48OF9rbUQkeApmREREJCY++OADt2cLZZjr1q0b9fMQyGRkZMQkmFm4cKHNmjUr3z8zZMgQt+HmiBEjCvW7RaR4KJgRERGRQlu1apVdeOGFdvjhh9t5551XqOdiNoW9aVq3bl2o5/FlnQuSatawYUNXvODOO+90gZCIxDcFMyIiIlJolDVmvcwjjzwSdXqZR/DRvn17K1myZKGeh+IDbIhZkGAG/fv3t1KlSrlZGhGJbwpmREREpFDYbJKNMW+//XbbeeedC/18BB+FTTHLuW6mIKpVq+aqmhGY/fXXXzE5DhEpGgpmREREJGrr1q2zCy64wA466CC7+OKLC/188+bNszlz5sQ0mGENzsaNGwv0c71797batWu7oEZE4peCGREREYnagAEDbO7cufb4449bSkrhuxV+X5hYBjPp6ek2ceLEAv0ca3aGDh3qNtHM7141IlL8FMyIiIhIVEjfGjlypOv077rrrjF7zgYNGhSqGlqktm3bWpkyZQqcaobu3bu7IgSsB8pveWcRKV4KZkRERKTASNvq0aOHdejQwa688sqYPW8s18ugdOnS1q5du6iCGTbeZCPNsWPH2nvvvRezYxKR2FEwIyIiIgXGbMzff/9tTzzxhOv0xwJ7y4wfPz6mwUy0RQC8o446yjp16mTXXXedbd68OabHJSKF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iZbMszP0o3LS3jJSEApmojB48OA8vz5o0KBiOxYRkbAbOnSoq1rEJsSM0ErxBjMEMqxRkOLDgGj9+vXd65+swUxe5syZ414jXQ8kP9RKovDWW29ts4nmrFmz3KK+XXbZRcGMiEg+UVyDBcBULmrVqlXQh5N06Ewfe+yxQR9GUkr2dTN5BTL0pe69917r1atX0IcjIaBgJgqMHubEngjdu3e3k046KZBjEhEJm02bNrn0MjYQZMdvKV5LliyxadOmafF/QHjdKXqRkZGhGYgIlGU+44wz7KabbrKzzjrLbUgukhclJMYIOZ+33nqr3XLLLUEfiohIKLDYf8qUKfbEE0+4dRtSvPzeWQpmgsHrvn79evcekG1TT6lupgqxkh8KZmK8mG327NlutFFERLaPHdCHDBniSrO2a9cu6MNJSqQ41apVyxo1ahT0oSQlNmNmRkapZtuiTV522WWu4tuiRYuCPhyJcwpmopSZmelSyyKR7810MWtnRERk+yVZSS9jfwmtMQx+s0y/UaEUr7S0NNtjjz0UzGzH9ddf7waJmaURyYuCmSh89tlnttNOO1mNGjWsefPmrgoP3njjDfvwww+DPjwRkbh2zz332A8//ODSy8qWLRv04SRtQEmamfaXCRbBpE/3k23T9/v3728PPfRQVj9LJDcKZqLQp08fO/roo23cuHFuZJEqPKAm+s033xz04YmIxC06JTfeeKO7ju6///5BH07S+uOPP2z16tVaLxMwgsmpU6duk+khW3GdqF27tt1www1BH4rEMQUzUZg+fboLYA444AC75pprskZV2rZta7/88kvQhyciEpfYCO+CCy5wnRMVSwkWqU0MwLFRqQTHB5PMVEruqXisrXvllVds/PjxQR+OxCkFM1Fo1qyZ21cGdevWdeUtwSiX39FWRESye/jhh23s2LH22GOPWfny5YM+HEv2YIZ1nhUrVgz6UJJa06ZNrXr16lo3k4ezzz7blW+/9tpr3XplkZwUzERh1KhRLo/zq6++ciONfBDQMFuz3377BX14IiJxh0qPzGRfeOGFdsghhwR9OEmPjAKlmAWP4gvaPDNvDBKzse7nn39uH3zwQdCHI3FIwUwUOnfubBMmTLCOHTu60YJ169a5ggAzZsxwC1tFROQ/jKYSxFSuXNntLSPBIouAlGgFM/FVBICBUcndMccc4/pczM5Q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WpVyybMoK17pfEs01G6kMNR+pLDUhsJD56r4KJjJJZq+6+M/7Y8Fqy01pYRt3hL9y+N/vnntitb38GZJU+87THS+JRpqN1IYaj9SWGpD4aFzVfQUzOSCl+TnOSvs2W9n2TuT51nGlkwrmVLC/bsj/vv4l42Uuu/byPZoUMVKxEsBctmGzrdEQ+1GCkPtRwpLbSg8dK6KloKZHVi2Nt2+nb7UJv+zwib/s9L9uzZ98zbfV750qrWpX8XaNqhiretVtv2aVLdqSVTjO1HofEs01G6kMNR+pLDUhsJD5yr2FMwUEC/X0rXp9vFnX9jZ5/awr8eNtSaNGlj18qUVJSfw+d6wabOlZ2yx0iVTrGypVJ1vyZPajRSG2o8UltpQuM7V5KkzrN0++9qTTz9rB3c6SOeqgEoW9AeSHQ2rRoUyVr1sCctYPs9qVyztPpfEPt8iBaF2I4Wh9iOFpTYUrnNVtVxJ27xqsdUqV8LqVy0X9CGFTtJumikiIiIiIuGmYEZEREREREJJwYyIiIiIiISSghkREREREQklBTMiIiIiIhJKCmZERERERCSUFMyIiIiIiEgoKZgREREREZFQUjAjIiIiIiKhpGBGRERERERCScGMiIiIiIiEkoIZEREREREJJQUzIiIiIiISSgpmREREREQklBTMiIiIiIhIKCmYERERERGRUFIwIyIiIiIioaRgRkREREREQknBjIiIiIiIhJKCGRERERERCSUFMyIiIiIiEkoKZkREREREJJQUzIiIiIiISCgpmBERERERkVBSMCMiIiIiIqGkYEZEREREREJJwYyIiIiIiISSghkREREREQklBTMiIiIiIhJKCmZERERERCSUFMyIiIiIiEgoKZgREREREZFQUjAjIiIiIiKhpGBGRERERERCScGMiIiIiIiEkoIZEREREREJJQUzIiIiIiISSgpmREREREQklBTMiIiIiIhIKCmYERERERGRUFIwIyIiIiIioaRgRkREREREQknBjIiIiIiIhJKCGRERERERCSUFMyIiIiIiEkoKZkREREREJJQUzIiIiIiISCgpmBERERERkVBSMCMiIiIiIqGkYEZEREREREJJwYyIiIiIiISSghkREREREQklBTMiIiIiIhJKCmZERERERCSUFMyIiIiIiEgoKZgREREREZFQUjAjIiIiIiKhpGBGRERERERCScGMiIiIiIiEkoIZEREREREJJQUzIiIiIiISSgpmREREREQklBTMiIiIiIhIKCmYERERERGRUFIwIyIiIiIioaRgRkREREREQknBjIiIiIiIhJKCGRERERERCSUFMyIiIiIiEkoKZkREREREJJQUzIiIiIiISCgpmBERERERCUjNmjXt7bfftj333DPoQwmlkkEfgIiIiIhIskpLS7OuXbsGfRihpZkZEREREREJJQUzIiIiIiISSgpmREREREQklBTMiIiIiIhIKCmYERERERGRUFIwIyIiIiISgPT0dFu2bNk2j2/evNlWrlwZyDGFjYIZEREREZEADB482E455ZRsj40ePdqqVq3qPjp27GhLliwJ7PjCQMGMiIiIiEgAPvroI+vRo0e2mZqePXu6j7Fjx1pGRoYNGDAg0GOMd9o0U0REREQkANOmTbM2bdpkfT5u3Dhbt26d3XbbbVa6dGkbNmyYde/ePdBjjHeamRERERERCcCmTZusYsWKWZ9/9913ttdee7lABo0bN7aFCxcGeITxT8GMiIiIiEgAGjRoYOPHj8/6/P3337dOnTplfU4gw9oZ2T6lmYmIiIiIBODUU0+1Pn362Jw5c+z333+377//3h588MGsr3/66ae2xx57BHqM8U7BjIiIiIhIAPr372/z5s1za2PKly9vjz/+uLVu3Trr6y1btnQVzWT7SmRmZmbm8XXJo/pEly5dbNasWdawYcOgD0dEREREJOloZkZEREREpJikpqZafucStmzZUuTHE3YKZkREREREigmbYnqkmA0aNMhtnLnvvvtmVTR75ZVXbMiQIQEeZXgomBERERERKSbHHXdc1v9ZssB6mfPOOy/rsbPOOsvatWtnr776qvXq1SugowwPlWYWEREREQkAm2QeeOCB2zx+0EEH2RdffBHIMYWNghkRERERkQDUqVPHnnvuuW0ef+aZZ9zXZMeUZiYiIiIiEoDhw4fb6aefbh9//HHWmplvv/3WJkyYYC+99FLQhxcKmpmJUsWKFW2vvfayUqVKBX0oIiIiIhJC3bp1sylTprg+5aRJk9wH62V++eUX9zXZMe0zIyIiIiIioaQ0MxERERGRgKxfv96ef/55++mnn6xChQrWpk0bl3pWsqS66fmhmRkRERERkQAsWrTIOnbsaEuWLLFdd93VrZXh3xIlStiHH35o9evXD/oQ456CGRERERGRALC/zOzZs+2tt96yxYsXu1mZ1atX24UXXmgrV660l19+OehDjHuavxIRERERCcB7771nr7/+uksvY5bGu+KKK+yAAw4I9NjCQtXMREREREQCwCxMbqlkqamplpKibnp+6FUSEREREQlAvXr1bObMmdkeS09Pt5tvvtkOOuigwI4rTBTMRIFGtmzZsm0e37x5s8tvFBERERHZkUMPPdRGjx6drbJZ1apVXSGAe+65J9BjCwsVAIjCDTfcYN999519+umnWY/REM855xxbs2aNHXjggfbGG29YjRo1Aj1OEREREYlf9BtXrVpldevWdSlnL7zwgjVt2tQ6d+6s0sz5pJmZKHz00UfWo0ePbDM1PXv2dB9jx461jIwMGzBgQKDHKCIiIiLxjYX/BDKgHPNJJ51khx12mAKZAlAwE4Vp06a50nneuHHjbN26dXbbbbe5/MZhw4a56hQiIiIiInl55plnrEmTJlapUiWrVauWKwjw4IMPBn1YoaGwLwqbNm2yihUrZn1Oytlee+1lpUuXdp83btzYFi5cGOARioiIiEi8e/TRR10Z5r59+7r1M/jss8/c52XKlMmWCSS5UzAThQYNGtj48eNt5513dp+///771qlTp6yvE8iweEtEREREZHtGjhzpMnouu+yyrMfoU9asWdPuuusuBTP5oGAmCqeeeqr16dPH5syZY7///rt9//332aYDKQzQtm3bQI9RREREROLb9OnT7aijjtrm8SOPPNL69esXyDGFjYKZKPTv39/mzZvnIuny5cvb448/bq1bt876esuWLa1jx46BHqOIiIiIxDcq31LNLCe2+qhevXogxxQ2Ks0cQ0uWLLEOHTrYjBkzgj4UEREREYlzrJfZZZddrHfv3tkeHzVqlP3999/uX8mbgpkojBkzxi3MYsdWigFEoqyef0m3bNkS0BGKiIiIiCQ+pZlFgUDm8MMPd1UnUlNTs00JsnHmm2++GejxiYiIiEh4Kdsn/zQzEwVK5c2ePfv/7d0HdJRV+sfxJ5MCMQFCEASEwFKkCAEBUVilKcUCCroquNjXRQREd1H8K1LUXRUV64KrKyqKnSKoFAWVKiqYoBQRIZQEAqQQkkAa//NcnJjJJCQMSd65yfdzzpxk3nlnuPNmOOf+5t77XFMLvKDExESpX78+IzIAAAAoEbN9Th8j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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Combine multiple prefabs if you have more than one available\n", + "combined_pipeline = combine_prefabs([\"preprocess\", \"similarity_clustering\"], new_name=\"CombinedPipeline\")\n", + "combined_pipeline.draw();" + ] + }, + { + "cell_type": "markdown", + "id": "0f4a9286", + "metadata": {}, + "source": [ + "Conclusion\n", + "---------\n", + "\n", + "In this tutorial, we learned how to:\n", + "\n", + "1. Load an example dataset from the ``AFL.double_agent.data`` module\n", + "2. List and load prefabricated pipelines from the ``AFL.double_agent.prefab`` module\n", + "3. Inspect the structure of a pipeline using ``.draw()`` and ``.print()`` methods\n", + "4. Generate and modify code for a pipeline using ``.print_code()``\n", + "5. Run a customized pipeline on a dataset and visualize the results\n", + "6. Combine multiple prefabricated pipelines\n", + "\n", + "Prefabricated pipelines provide a convenient way to reuse and share pipeline configurations, making your analysis workflows more efficient and reproducible." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "venv", + "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.11.10" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +}