Parametric Analysis with MorphingIterator (v4 Update)
This notebook demonstrates the most powerful feature of the pyfwg library: the MorphingIterator class.
This class is designed for running parametric studies, where you need to execute the morphing process multiple times with different parameters (e.g., different GCMs, interpolation methods, or even different EPW files). It uses a Pandas DataFrame to define all the runs in a structured and easy-to-manage way.
Note: pyfwg now fully supports FutureWeatherGenerator v4.0.x (Global) and v2.0.x (Europe), which include a new keyword-based CLI, support for string-based parameter options, and additional output formats (like 'MET' or 'CSV').
The Iterator Workflow
The iterator is designed to be used in a clear, multi-step process that provides control and visibility at each stage:
Instantiate the Iterator: Choose which tool you want to work with (
MorphingWorkflowGlobalorMorphingWorkflowEurope).Set Default Values: Define parameters that are common to all runs in your batch.
Define the Runs DataFrame: Specify the parameters that will change for each run, using either an Excel file or a Pandas DataFrame directly.
Generate the Plan & Prepare Workflows: A single command that applies all defaults, validates the plan, and prepares all the workflow instances for execution.
Execute the Workflows: A final command to run the entire batch of simulations.
Step 1: Instantiate the Iterator
First, we import the necessary classes and create an instance of the MorphingIterator. We must tell it which workflow class it will be managing. In this example, we’ll use MorphingWorkflowGlobal.
[1]:
import pandas as pd
import os
from pyfwg import MorphingIterator, MorphingWorkflowGlobal, export_template_to_excel, load_runs_from_excel, get_available_lczs, DEFAULT_GLOBAL_GCMS
# We specify that we want to use the Global tool for all runs.
iterator = MorphingIterator(workflow_class=MorphingWorkflowGlobal)
2025-12-31 08:49:54 - INFO - MorphingIterator initialized for MorphingWorkflowGlobal.
Step 2: Pre-flight Checks & Common Parameters
Before defining a large batch of runs, it’s good practice to check which parameters are valid. Here, we’ll get the available LCZs for our weather files. Then, we’ll use set_default_values to define parameters that will be the same for all runs, such as the JAR path and the LCZs we just validated.
[2]:
# !!! IMPORTANT: Update this path to your V4 JAR !!!
jar_path = r"D:\OneDrive - Universidad de Cádiz (uca.es)\Programas\FutureWeatherGenerator_v4.0.2.jar"
epw_files_dir = 'epws/wo_pattern'
epw_files = [os.path.join(epw_files_dir, f) for f in os.listdir(epw_files_dir) if f.endswith('.epw')]
# Get available LCZs for each EPW file to ensure our choices are valid.
available_lczs = get_available_lczs(
epw_paths=epw_files,
fwg_jar_path=jar_path,
)
2025-12-31 08:50:48 - INFO - --- Fetching available LCZs for 2 EPW file(s) ---
2025-12-31 08:50:48 - INFO - Checking LCZ pair (Original: 0, Target: 0) availability for GBR_London.Gatwick.037760_IWEC_uhi_type-2.epw...
2025-12-31 08:50:48 - INFO - --- Applying UHI effect to GBR_London.Gatwick.037760_IWEC_uhi_type-2.epw ---
2025-12-31 08:50:48 - INFO - Executing command: java -jar "D:\OneDrive - Universidad de Cádiz (uca.es)\Programas\FutureWeatherGenerator_v4.0.2.jar" -u -epw=C:\Users\sanga\AppData\Local\Temp\tmpi4zkf7rl\GBR_London.Gatwick.037760_IWEC_uhi_type-2.epw -output_folder=C:\Users\sanga\AppData\Local\Temp\tmpi4zkf7rl\ -uhi=true:0:0 -output_type=EPW
2025-12-31 08:51:02 - INFO - Available LCZs for 'GBR_London.Gatwick.037760_IWEC_uhi_type-2.epw': [1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 14, 15, 17]
2025-12-31 08:51:02 - INFO - Checking LCZ pair (Original: 0, Target: 0) availability for sevilla_in_this_one_the_uhi_is_type-1.epw...
2025-12-31 08:51:02 - INFO - --- Applying UHI effect to sevilla_in_this_one_the_uhi_is_type-1.epw ---
2025-12-31 08:51:02 - INFO - Executing command: java -jar "D:\OneDrive - Universidad de Cádiz (uca.es)\Programas\FutureWeatherGenerator_v4.0.2.jar" -u -epw=C:\Users\sanga\AppData\Local\Temp\tmpilqkeeuq\sevilla_in_this_one_the_uhi_is_type-1.epw -output_folder=C:\Users\sanga\AppData\Local\Temp\tmpilqkeeuq\ -uhi=true:0:0 -output_type=EPW
2025-12-31 08:51:16 - INFO - Available LCZs for 'sevilla_in_this_one_the_uhi_is_type-1.epw': [2, 3, 6, 8, 9, 11, 12, 13, 14, 16]
The available LCZs for the epw files are:
[3]:
print(available_lczs)
{'GBR_London.Gatwick.037760_IWEC_uhi_type-2.epw': [1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 14, 15, 17], 'sevilla_in_this_one_the_uhi_is_type-1.epw': [2, 3, 6, 8, 9, 11, 12, 13, 14, 16]}
[2]:
# Define the keyword mapping rules that will be used for all runs in this batch.
mapping_rules = {
'city': {
'seville': ['sevilla', 'SVQ'],
'london': ['london', 'gatwick']
},
'uhi': {
'type-1': 'type-1',
'type-2': 'type-2'
}
}
2025-12-30 10:30:11 - INFO - --- Fetching available LCZs for 2 EPW file(s) ---
2025-12-30 10:30:11 - INFO - Checking LCZ pair (Original: 0, Target: 0) availability for GBR_London.Gatwick.037760_IWEC_uhi_type-2.epw...
2025-12-30 10:30:11 - INFO - --- Applying UHI effect to GBR_London.Gatwick.037760_IWEC_uhi_type-2.epw ---
2025-12-30 10:30:11 - INFO - Executing command: java -jar "D:\OneDrive - Universidad de Cádiz (uca.es)\Programas\FutureWeatherGenerator_v4.0.2.jar" -u -epw=C:\Users\sanga\AppData\Local\Temp\tmps4z54yza\GBR_London.Gatwick.037760_IWEC_uhi_type-2.epw -output_folder=C:\Users\sanga\AppData\Local\Temp\tmps4z54yza\ -uhi=true:0:0 -output_type=EPW
2025-12-30 10:30:26 - INFO - Available LCZs for 'GBR_London.Gatwick.037760_IWEC_uhi_type-2.epw': [2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 14, 15, 17]
2025-12-30 10:30:26 - INFO - Checking LCZ pair (Original: 0, Target: 0) availability for sevilla_in_this_one_the_uhi_is_type-1.epw...
2025-12-30 10:30:26 - INFO - --- Applying UHI effect to sevilla_in_this_one_the_uhi_is_type-1.epw ---
2025-12-30 10:30:26 - INFO - Executing command: java -jar "D:\OneDrive - Universidad de Cádiz (uca.es)\Programas\FutureWeatherGenerator_v4.0.2.jar" -u -epw=C:\Users\sanga\AppData\Local\Temp\tmpyvd_1evq\sevilla_in_this_one_the_uhi_is_type-1.epw -output_folder=C:\Users\sanga\AppData\Local\Temp\tmpyvd_1evq\ -uhi=true:0:0 -output_type=EPW
2025-12-30 10:30:40 - INFO - Available LCZs for 'sevilla_in_this_one_the_uhi_is_type-1.epw': [3, 6, 8, 9, 11, 12, 13, 14, 16]
set_default_values Parameters
This method allows you to define parameters that are common to all runs in your batch, so you don’t have to repeat them in every row of your DataFrame. All arguments are optional.
Workflow Control Parameters
final_output_dir(str): A default output directory for runs that don’t specify one.output_filename_pattern(str): A default renaming pattern. Must contain{ssp}/{rcp}and{year}.scenario_mapping(Dict): A default dictionary for mapping scenario names.fwg_jar_path(str): The path to the Future Weather Generator.jarfile.run_incomplete_files(bool, default:False): IfTrue, also processes partially categorized files.delete_temp_files(bool, default:True): IfTrue, deletes temporary folders after processing.temp_base_dir(str): A default base directory for temporary files.fwg_show_tool_output(bool, default:False): IfTrue, prints the FWG tool’s console output in real-time.fwg_params(Dict, default:None): A dictionary for base FWG parameters.
Future Weather Generator Tool Parameters
fwg_gcms(List[str], default:None): For Global tool only. A default list of GCMs to use.fwg_rcm_pairs(List[str], default:None): For Europe tool only. A default list of GCM-RCM pairs to use.fwg_create_ensemble(bool, default:True): IfTrue, creates an ensemble from the selected models.fwg_winter_sd_shift(float, default:0.0): Winter standard deviation shift.fwg_summer_sd_shift(float, default:0.0): Summer standard deviation shift.fwg_month_transition_hours(int, default:72): Hours for month transition.fwg_use_multithreading(bool, default:True): Use multithreading.fwg_interpolation_method_id(Union[int, str], default:0): Interpolation method ID or string (e.g.,'AVG4P'for V4).fwg_limit_variables(bool, default:True): Limit variables to physical bounds.fwg_solar_hour_adjustment(Union[int, str], default:1): Solar hour adjustment option (e.g.,'By_Month'for V4).fwg_diffuse_irradiation_model(Union[int, str], default:1): Diffuse irradiation model option (e.g.,'Engerer_2015'for V4).fwg_add_uhi(bool, default:True): Add UHI effect.fwg_epw_original_lcz(int, default:14): Original EPW LCZ.fwg_target_uhi_lcz(int, default:1): Target UHI LCZ.fwg_output_type(str, default:'EPW'): V4 feature. Format of output files:'EPW','MET', or'CSV'.fwg_version(Optional[str], default:None): Force a specific version CLI (e.g.,'4').
[3]:
# Set the default values that will be common to all runs.
iterator.set_default_values(
fwg_jar_path=jar_path,
output_filename_pattern='{city}_{uhi}_gcm-{fwg_gcms}_{ssp}_{year}',
# We just checked that LCZs 2 and 3 are available in all epws, so we can use them as defaults.
fwg_epw_original_lcz=2,
fwg_target_uhi_lcz=3,
fwg_version='4' # We are using v4
)
2025-12-30 10:30:41 - INFO - Custom default values have been set for the iterator: {'output_filename_pattern': '{city}_{uhi}_gcm-{fwg_gcms}_{ssp}_{year}', 'fwg_jar_path': 'D:\\OneDrive - Universidad de Cádiz (uca.es)\\Programas\\FutureWeatherGenerator_v4.0.2.jar', 'fwg_epw_original_lcz': 2, 'fwg_target_uhi_lcz': 3, 'fwg_version': '4'}
Step 3: Define the Runs DataFrame
This is where you specify what will change between each run. You have three flexible options for this.
Step 3.1: Option A - Using an Excel Template
This is the recommended approach for non-programmers or for managing a large number of runs. You can export a blank template, fill it in with your scenarios, and load it back into pyfwg.
[4]:
# 1. Export the blank template to an Excel file.
template_path = 'my_parametric_study.xlsx'
export_template_to_excel(iterator, file_path=template_path)
print(f"--- Original Template Structure (saved to '{template_path}') ---")
# Read and display the empty template to show the available columns.
pd.read_excel(template_path)
2025-12-30 10:30:41 - INFO - Generating Excel template for MorphingWorkflowGlobal...
2025-12-30 10:30:41 - INFO - Template successfully exported to 'D:\Python\pyfwg\docs\source\tutorials\my_parametric_study.xlsx'
--- Original Template Structure (saved to 'my_parametric_study.xlsx') ---
[4]:
| epw_paths | input_filename_pattern | keyword_mapping | final_output_dir | output_filename_pattern | scenario_mapping | fwg_jar_path | run_incomplete_files | delete_temp_files | temp_base_dir | ... | fwg_use_multithreading | fwg_interpolation_method_id | fwg_limit_variables | fwg_solar_hour_adjustment | fwg_diffuse_irradiation_model | fwg_add_uhi | fwg_epw_original_lcz | fwg_target_uhi_lcz | fwg_output_type | fwg_version |
|---|
0 rows × 27 columns
[5]:
# --- At this point, you would open 'my_parametric_study.xlsx', ---
# --- fill in the rows with your scenarios, and save it. ---
# --- For this example, we assume you saved it as 'my_parametric_study_modified.xlsx' ---
[6]:
# 2. Load the completed scenarios from your edited Excel file.
template_path_mod = 'my_parametric_study_modified.xlsx'
runs_from_excel = load_runs_from_excel(template_path_mod)
print("\n--- Runs Loaded from Excel (Data types are now correct) ---")
runs_from_excel
2025-12-30 10:30:42 - INFO - Loading runs from 'my_parametric_study_modified.xlsx'...
2025-12-30 10:30:42 - INFO - Runs loaded and data types converted successfully.
--- Runs Loaded from Excel (Data types are now correct) ---
[6]:
| epw_paths | input_filename_pattern | keyword_mapping | final_output_dir | output_filename_pattern | scenario_mapping | fwg_jar_path | run_incomplete_files | delete_temp_files | temp_base_dir | ... | fwg_summer_sd_shift | fwg_month_transition_hours | fwg_use_multithreading | fwg_interpolation_method_id | fwg_limit_variables | fwg_solar_hour_adjustment | fwg_diffuse_irradiation_model | fwg_add_uhi | fwg_epw_original_lcz | fwg_target_uhi_lcz | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | epws/wo_pattern/GBR_London.Gatwick.037760_IWEC... | NaN | NaN | results_using_excel/london | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
| 1 | epws/wo_pattern/sevilla_in_this_one_the_uhi_is... | NaN | NaN | results_using_excel/seville | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
2 rows × 25 columns
Step 3.2: Option B - Using a Pandas DataFrame Directly
For quick tests or when working within a script, you can define your runs programmatically.
[7]:
# Get the blank template DataFrame.
runs_df_direct = iterator.get_template_dataframe()
# --- Run 1: Run the first EPW file with one set of GCMs ---
runs_df_direct.loc[0] = {
'epw_paths': epw_files[0],
'final_output_dir': './results/0',
'fwg_gcms': ['CanESM5']
}
# --- Run 2: Run the second EPW file with a different GCM ---
runs_df_direct.loc[1] = {
'epw_paths': epw_files[1],
'final_output_dir': './results/1',
'fwg_gcms': ['MIROC6']
}
print("--- Runs Defined Directly in Pandas ---")
runs_df_direct
--- Runs Defined Directly in Pandas ---
[7]:
| epw_paths | input_filename_pattern | keyword_mapping | final_output_dir | output_filename_pattern | scenario_mapping | fwg_jar_path | run_incomplete_files | delete_temp_files | temp_base_dir | ... | fwg_use_multithreading | fwg_interpolation_method_id | fwg_limit_variables | fwg_solar_hour_adjustment | fwg_diffuse_irradiation_model | fwg_add_uhi | fwg_epw_original_lcz | fwg_target_uhi_lcz | fwg_output_type | fwg_version | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | epws/wo_pattern\GBR_London.Gatwick.037760_IWEC... | NaN | NaN | ./results/0 | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
| 1 | epws/wo_pattern\sevilla_in_this_one_the_uhi_is... | NaN | NaN | ./results/1 | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
2 rows × 27 columns
Step 3.3: Option C - Hybrid Approach (Load from Excel, then Modify)
You can also combine the two methods. Here, we load the runs from our Excel file and then programmatically add a new run to the DataFrame.
[8]:
first_gcm = list(DEFAULT_GLOBAL_GCMS)[0]
runs_df_hybrid = runs_from_excel.copy() if 'runs_from_excel' in locals() else runs_df_direct.copy()
# Add a new row (run) to the DataFrame.
runs_df_hybrid.loc[len(runs_df_hybrid)] = {
'epw_paths': epw_files[1],
'final_output_dir': 'results_hybrid/seville',
'fwg_gcms': [first_gcm]
}
print("--- Final DataFrame for Execution (Hybrid) ---")
runs_df_hybrid
--- Final DataFrame for Execution (Hybrid) ---
[8]:
| epw_paths | input_filename_pattern | keyword_mapping | final_output_dir | output_filename_pattern | scenario_mapping | fwg_jar_path | run_incomplete_files | delete_temp_files | temp_base_dir | ... | fwg_summer_sd_shift | fwg_month_transition_hours | fwg_use_multithreading | fwg_interpolation_method_id | fwg_limit_variables | fwg_solar_hour_adjustment | fwg_diffuse_irradiation_model | fwg_add_uhi | fwg_epw_original_lcz | fwg_target_uhi_lcz | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | epws/wo_pattern/GBR_London.Gatwick.037760_IWEC... | NaN | NaN | results_using_excel/london | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
| 1 | epws/wo_pattern/sevilla_in_this_one_the_uhi_is... | NaN | NaN | results_using_excel/seville | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
| 2 | epws/wo_pattern\sevilla_in_this_one_the_uhi_is... | NaN | NaN | results_hybrid/seville | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
3 rows × 25 columns
Step 4: Generate the Morphing Workflows and Execution Plan
This single method is the core of the planning phase. It takes your DataFrame of runs, applies all defaults, maps the file categories, and prepares all the underlying workflow instances.
Crucially, it also performs a robust validation check to prevent accidental file overwrites. It simulates all final output filenames and, if any collisions are found, it provides a comprehensive report of all conflicting files, making it much easier to debug your output_filename_pattern.
The final, detailed execution plan is stored in the iterator.morphing_workflows_plan_df attribute for you to review.
generate_morphing_workflows Parameters
This is the core planning method. It takes your DataFrame of runs and prepares everything for execution.
runs_df(pd.DataFrame): Required. The user’s DataFrame of runs, where each row represents a unique configuration.input_filename_pattern(Optional[str], default:None): A regex pattern for filename mapping, applied as a default to every run unless overridden in the DataFrame.keyword_mapping(Optional[Dict], default:None): A dictionary of keyword rules for filename mapping, applied as a default to every run unless overridden in the DataFrame.raise_on_overwrite(bool, default:True): Controls the behavior when a filename collision is detected. IfTrue(the default and recommended setting), the method will raise aValueErrorto stop execution and prevent data loss. IfFalse, it will only print a warning and allow the process to continue.
[9]:
# The mapping strategy is a static argument for the whole batch.
iterator.generate_morphing_workflows(
runs_df=runs_df_hybrid,
keyword_mapping=mapping_rules
)
2025-12-30 10:30:44 - INFO - Generating detailed execution plan and preparing workflows...
2025-12-30 10:30:44 - INFO - --- Step 1: Mapping categories from filenames ---
2025-12-30 10:30:44 - INFO - Mapped 'epws/wo_pattern/GBR_London.Gatwick.037760_IWEC_uhi_type-2.epw': {'city': 'london', 'uhi': 'type-2'}
2025-12-30 10:30:44 - INFO - Category mapping complete.
2025-12-30 10:30:44 - INFO - --- Step 1: Mapping categories from filenames ---
2025-12-30 10:30:44 - INFO - Mapped 'epws/wo_pattern/sevilla_in_this_one_the_uhi_is_type-1.epw': {'city': 'seville', 'uhi': 'type-1'}
2025-12-30 10:30:44 - INFO - Category mapping complete.
2025-12-30 10:30:44 - INFO - --- Step 1: Mapping categories from filenames ---
2025-12-30 10:30:44 - INFO - Mapped 'epws/wo_pattern\sevilla_in_this_one_the_uhi_is_type-1.epw': {'city': 'seville', 'uhi': 'type-1'}
2025-12-30 10:30:44 - INFO - Category mapping complete.
2025-12-30 10:30:44 - INFO - Validating for potential filename overwrites...
2025-12-30 10:30:44 - INFO - Filename validation passed. No overwrites detected.
2025-12-30 10:30:44 - INFO - Preparing 3 workflow instances...
2025-12-30 10:30:44 - INFO - --- Step 1: Mapping categories from filenames ---
2025-12-30 10:30:44 - INFO - Mapped 'epws/wo_pattern/GBR_London.Gatwick.037760_IWEC_uhi_type-2.epw': {'city': 'london', 'uhi': 'type-2'}
2025-12-30 10:30:44 - INFO - Category mapping complete.
2025-12-30 10:30:44 - INFO - --- Step 2: Configuring and Previewing Morphing Plan ---
2025-12-30 10:30:44 - INFO - --- Step 1: Mapping categories from filenames ---
2025-12-30 10:30:44 - INFO - Mapped 'epws/wo_pattern/sevilla_in_this_one_the_uhi_is_type-1.epw': {'city': 'seville', 'uhi': 'type-1'}
2025-12-30 10:30:44 - INFO - Category mapping complete.
2025-12-30 10:30:44 - INFO - --- Step 2: Configuring and Previewing Morphing Plan ---
2025-12-30 10:30:44 - INFO - --- Step 1: Mapping categories from filenames ---
2025-12-30 10:30:44 - INFO - Mapped 'epws/wo_pattern\sevilla_in_this_one_the_uhi_is_type-1.epw': {'city': 'seville', 'uhi': 'type-1'}
2025-12-30 10:30:44 - INFO - Category mapping complete.
2025-12-30 10:30:44 - INFO - --- Step 2: Configuring and Previewing Morphing Plan ---
2025-12-30 10:30:44 - INFO - Execution plan generated and 3 workflows prepared.
============================================================
MORPHING CONFIGURATION & PREVIEW
============================================================
- FWG JAR Path: D:\OneDrive - Universidad de Cádiz (uca.es)\Programas\FutureWeatherGenerator_v4.0.2.jar
- Final Output Directory: D:\Python\pyfwg\docs\source\tutorials\results_using_excel\london
- EPWs to be Morphed (1 files):
- GBR_London.Gatwick.037760_IWEC_uhi_type-2.epw
For input file: GBR_London.Gatwick.037760_IWEC_uhi_type-2.epw
-> Generated 'ssp126_2050.epw' will be moved to: D:\Python\pyfwg\docs\source\tutorials\results_using_excel\london\london_type-2_gcm-['CanESM5']_ssp126_2050.epw
-> Generated 'ssp245_2050.epw' will be moved to: D:\Python\pyfwg\docs\source\tutorials\results_using_excel\london\london_type-2_gcm-['CanESM5']_ssp245_2050.epw
-> Generated 'ssp370_2050.epw' will be moved to: D:\Python\pyfwg\docs\source\tutorials\results_using_excel\london\london_type-2_gcm-['CanESM5']_ssp370_2050.epw
-> Generated 'ssp585_2050.epw' will be moved to: D:\Python\pyfwg\docs\source\tutorials\results_using_excel\london\london_type-2_gcm-['CanESM5']_ssp585_2050.epw
-> Generated 'ssp126_2080.epw' will be moved to: D:\Python\pyfwg\docs\source\tutorials\results_using_excel\london\london_type-2_gcm-['CanESM5']_ssp126_2080.epw
-> Generated 'ssp245_2080.epw' will be moved to: D:\Python\pyfwg\docs\source\tutorials\results_using_excel\london\london_type-2_gcm-['CanESM5']_ssp245_2080.epw
-> Generated 'ssp370_2080.epw' will be moved to: D:\Python\pyfwg\docs\source\tutorials\results_using_excel\london\london_type-2_gcm-['CanESM5']_ssp370_2080.epw
-> Generated 'ssp585_2080.epw' will be moved to: D:\Python\pyfwg\docs\source\tutorials\results_using_excel\london\london_type-2_gcm-['CanESM5']_ssp585_2080.epw
============================================================
Configuration set. Call execute_morphing() to start the process.
============================================================
MORPHING CONFIGURATION & PREVIEW
============================================================
- FWG JAR Path: D:\OneDrive - Universidad de Cádiz (uca.es)\Programas\FutureWeatherGenerator_v4.0.2.jar
- Final Output Directory: D:\Python\pyfwg\docs\source\tutorials\results_using_excel\seville
- EPWs to be Morphed (1 files):
- sevilla_in_this_one_the_uhi_is_type-1.epw
For input file: sevilla_in_this_one_the_uhi_is_type-1.epw
-> Generated 'ssp126_2050.epw' will be moved to: D:\Python\pyfwg\docs\source\tutorials\results_using_excel\seville\seville_type-1_gcm-['MIROC6']_ssp126_2050.epw
-> Generated 'ssp245_2050.epw' will be moved to: D:\Python\pyfwg\docs\source\tutorials\results_using_excel\seville\seville_type-1_gcm-['MIROC6']_ssp245_2050.epw
-> Generated 'ssp370_2050.epw' will be moved to: D:\Python\pyfwg\docs\source\tutorials\results_using_excel\seville\seville_type-1_gcm-['MIROC6']_ssp370_2050.epw
-> Generated 'ssp585_2050.epw' will be moved to: D:\Python\pyfwg\docs\source\tutorials\results_using_excel\seville\seville_type-1_gcm-['MIROC6']_ssp585_2050.epw
-> Generated 'ssp126_2080.epw' will be moved to: D:\Python\pyfwg\docs\source\tutorials\results_using_excel\seville\seville_type-1_gcm-['MIROC6']_ssp126_2080.epw
-> Generated 'ssp245_2080.epw' will be moved to: D:\Python\pyfwg\docs\source\tutorials\results_using_excel\seville\seville_type-1_gcm-['MIROC6']_ssp245_2080.epw
-> Generated 'ssp370_2080.epw' will be moved to: D:\Python\pyfwg\docs\source\tutorials\results_using_excel\seville\seville_type-1_gcm-['MIROC6']_ssp370_2080.epw
-> Generated 'ssp585_2080.epw' will be moved to: D:\Python\pyfwg\docs\source\tutorials\results_using_excel\seville\seville_type-1_gcm-['MIROC6']_ssp585_2080.epw
============================================================
Configuration set. Call execute_morphing() to start the process.
============================================================
MORPHING CONFIGURATION & PREVIEW
============================================================
- FWG JAR Path: D:\OneDrive - Universidad de Cádiz (uca.es)\Programas\FutureWeatherGenerator_v4.0.2.jar
- Final Output Directory: D:\Python\pyfwg\docs\source\tutorials\results_hybrid\seville
- EPWs to be Morphed (1 files):
- sevilla_in_this_one_the_uhi_is_type-1.epw
For input file: sevilla_in_this_one_the_uhi_is_type-1.epw
-> Generated 'ssp126_2050.epw' will be moved to: D:\Python\pyfwg\docs\source\tutorials\results_hybrid\seville\seville_type-1_gcm-['EC_Earth3']_ssp126_2050.epw
-> Generated 'ssp245_2050.epw' will be moved to: D:\Python\pyfwg\docs\source\tutorials\results_hybrid\seville\seville_type-1_gcm-['EC_Earth3']_ssp245_2050.epw
-> Generated 'ssp370_2050.epw' will be moved to: D:\Python\pyfwg\docs\source\tutorials\results_hybrid\seville\seville_type-1_gcm-['EC_Earth3']_ssp370_2050.epw
-> Generated 'ssp585_2050.epw' will be moved to: D:\Python\pyfwg\docs\source\tutorials\results_hybrid\seville\seville_type-1_gcm-['EC_Earth3']_ssp585_2050.epw
-> Generated 'ssp126_2080.epw' will be moved to: D:\Python\pyfwg\docs\source\tutorials\results_hybrid\seville\seville_type-1_gcm-['EC_Earth3']_ssp126_2080.epw
-> Generated 'ssp245_2080.epw' will be moved to: D:\Python\pyfwg\docs\source\tutorials\results_hybrid\seville\seville_type-1_gcm-['EC_Earth3']_ssp245_2080.epw
-> Generated 'ssp370_2080.epw' will be moved to: D:\Python\pyfwg\docs\source\tutorials\results_hybrid\seville\seville_type-1_gcm-['EC_Earth3']_ssp370_2080.epw
-> Generated 'ssp585_2080.epw' will be moved to: D:\Python\pyfwg\docs\source\tutorials\results_hybrid\seville\seville_type-1_gcm-['EC_Earth3']_ssp585_2080.epw
============================================================
Configuration set. Call execute_morphing() to start the process.
[10]:
print("--- Detailed Execution Plan ---")
# Display key columns to verify the plan, including the new category columns.
display_cols = [
'epw_paths',
'final_output_dir',
'fwg_gcms',
'cat_city',
'cat_uhi'
]
iterator.morphing_workflows_plan_df[display_cols]
--- Detailed Execution Plan ---
[10]:
| epw_paths | final_output_dir | fwg_gcms | cat_city | cat_uhi | |
|---|---|---|---|---|---|
| 0 | epws/wo_pattern/GBR_London.Gatwick.037760_IWEC... | results_using_excel/london | [CanESM5] | [london] | [type-2] |
| 1 | epws/wo_pattern/sevilla_in_this_one_the_uhi_is... | results_using_excel/seville | [MIROC6] | [seville] | [type-1] |
| 2 | epws/wo_pattern\sevilla_in_this_one_the_uhi_is... | results_hybrid/seville | [EC_Earth3] | [seville] | [type-1] |
[11]:
# At this point the default values have been applied, and therefore the plan can be fully checked before running the morphing
iterator.morphing_workflows_plan_df
[11]:
| epw_paths | input_filename_pattern | keyword_mapping | cat_city | cat_uhi | final_output_dir | output_filename_pattern | scenario_mapping | fwg_jar_path | run_incomplete_files | ... | fwg_use_multithreading | fwg_interpolation_method_id | fwg_limit_variables | fwg_solar_hour_adjustment | fwg_diffuse_irradiation_model | fwg_add_uhi | fwg_epw_original_lcz | fwg_target_uhi_lcz | fwg_output_type | fwg_version | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | epws/wo_pattern/GBR_London.Gatwick.037760_IWEC... | None | {'city': {'seville': ['sevilla', 'SVQ'], 'lond... | [london] | [type-2] | results_using_excel/london | {city}_{uhi}_gcm-{fwg_gcms}_{ssp}_{year} | NaN | D:\OneDrive - Universidad de Cádiz (uca.es)\Pr... | False | ... | True | 0 | True | 1 | 1 | True | 2 | 3 | EPW | 4 |
| 1 | epws/wo_pattern/sevilla_in_this_one_the_uhi_is... | None | {'city': {'seville': ['sevilla', 'SVQ'], 'lond... | [seville] | [type-1] | results_using_excel/seville | {city}_{uhi}_gcm-{fwg_gcms}_{ssp}_{year} | NaN | D:\OneDrive - Universidad de Cádiz (uca.es)\Pr... | False | ... | True | 0 | True | 1 | 1 | True | 2 | 3 | EPW | 4 |
| 2 | epws/wo_pattern\sevilla_in_this_one_the_uhi_is... | None | {'city': {'seville': ['sevilla', 'SVQ'], 'lond... | [seville] | [type-1] | results_hybrid/seville | {city}_{uhi}_gcm-{fwg_gcms}_{ssp}_{year} | NaN | D:\OneDrive - Universidad de Cádiz (uca.es)\Pr... | False | ... | True | 0 | True | 1 | 1 | True | 2 | 3 | EPW | 4 |
3 rows × 29 columns
You can also inspect the prepared workflow instances themselves.
[12]:
print("\n--- Inspecting first prepared workflow ---")
if iterator.prepared_workflows:
first_workflow = iterator.prepared_workflows[0]
print(f"Is config valid? {first_workflow.is_config_valid}")
print(f"Files to be morphed: {[os.path.basename(p) for p in first_workflow.epws_to_be_morphed]}")
else:
print("No workflows were prepared, likely due to errors in the plan.")
--- Inspecting first prepared workflow ---
Is config valid? True
Files to be morphed: ['GBR_London.Gatwick.037760_IWEC_uhi_type-2.epw']
Step 5: Execute the Morphing Workflows
This is the final step. The run_morphing_workflows method takes no arguments to define the runs, as it simply executes the workflows that were prepared in the previous step.
run_morphing_workflows Parameters
show_tool_output(Optional[bool], default:None): A flag to globally override the console output setting for all workflows in this specific batch execution.If set to
TrueorFalse, it will force this behavior for all runs, ignoring thefwg_show_tool_outputvalue in the plan.If left as
None(the default), each run will use thefwg_show_tool_outputvalue that was defined for it in the execution plan.
[ ]:
iterator.run_morphing_workflows(show_tool_output=False)
Let’s have a look at the files we just generated:
[18]:
output_paths = [i for i in iterator.morphing_workflows_plan_df['final_output_dir']]
for output_path in output_paths:
print(f"\n--- Files in '{output_path}' ---")
for file in os.listdir(output_path):
print(file)
['results_using_excel/london', 'results_using_excel/seville', 'results_hybrid/seville']
--- Files in 'results_using_excel/london' ---
london_type-2_gcm-['CanESM5']_ssp126_2050.epw
london_type-2_gcm-['CanESM5']_ssp126_2050.stat
london_type-2_gcm-['CanESM5']_ssp126_2080.epw
london_type-2_gcm-['CanESM5']_ssp126_2080.stat
london_type-2_gcm-['CanESM5']_ssp245_2050.epw
london_type-2_gcm-['CanESM5']_ssp245_2050.stat
london_type-2_gcm-['CanESM5']_ssp245_2080.epw
london_type-2_gcm-['CanESM5']_ssp245_2080.stat
london_type-2_gcm-['CanESM5']_ssp370_2050.epw
london_type-2_gcm-['CanESM5']_ssp370_2050.stat
london_type-2_gcm-['CanESM5']_ssp370_2080.epw
london_type-2_gcm-['CanESM5']_ssp370_2080.stat
london_type-2_gcm-['CanESM5']_ssp585_2050.epw
london_type-2_gcm-['CanESM5']_ssp585_2050.stat
london_type-2_gcm-['CanESM5']_ssp585_2080.epw
london_type-2_gcm-['CanESM5']_ssp585_2080.stat
--- Files in 'results_using_excel/seville' ---
seville_type-1_gcm-['MIROC6']_ssp126_2050.epw
seville_type-1_gcm-['MIROC6']_ssp126_2050.stat
seville_type-1_gcm-['MIROC6']_ssp126_2080.epw
seville_type-1_gcm-['MIROC6']_ssp126_2080.stat
seville_type-1_gcm-['MIROC6']_ssp245_2050.epw
seville_type-1_gcm-['MIROC6']_ssp245_2050.stat
seville_type-1_gcm-['MIROC6']_ssp245_2080.epw
seville_type-1_gcm-['MIROC6']_ssp245_2080.stat
seville_type-1_gcm-['MIROC6']_ssp370_2050.epw
seville_type-1_gcm-['MIROC6']_ssp370_2050.stat
seville_type-1_gcm-['MIROC6']_ssp370_2080.epw
seville_type-1_gcm-['MIROC6']_ssp370_2080.stat
seville_type-1_gcm-['MIROC6']_ssp585_2050.epw
seville_type-1_gcm-['MIROC6']_ssp585_2050.stat
seville_type-1_gcm-['MIROC6']_ssp585_2080.epw
seville_type-1_gcm-['MIROC6']_ssp585_2080.stat
--- Files in 'results_hybrid/seville' ---
seville_type-1_gcm-['EC_Earth3']_ssp126_2050.epw
seville_type-1_gcm-['EC_Earth3']_ssp126_2050.stat
seville_type-1_gcm-['EC_Earth3']_ssp126_2080.epw
seville_type-1_gcm-['EC_Earth3']_ssp126_2080.stat
seville_type-1_gcm-['EC_Earth3']_ssp245_2050.epw
seville_type-1_gcm-['EC_Earth3']_ssp245_2050.stat
seville_type-1_gcm-['EC_Earth3']_ssp245_2080.epw
seville_type-1_gcm-['EC_Earth3']_ssp245_2080.stat
seville_type-1_gcm-['EC_Earth3']_ssp370_2050.epw
seville_type-1_gcm-['EC_Earth3']_ssp370_2050.stat
seville_type-1_gcm-['EC_Earth3']_ssp370_2080.epw
seville_type-1_gcm-['EC_Earth3']_ssp370_2080.stat
seville_type-1_gcm-['EC_Earth3']_ssp585_2050.epw
seville_type-1_gcm-['EC_Earth3']_ssp585_2050.stat
seville_type-1_gcm-['EC_Earth3']_ssp585_2080.epw
seville_type-1_gcm-['EC_Earth3']_ssp585_2080.stat
Cleaning up
Once the workflow is finished, you can delete the temporary folders created during the process if you don’t need them anymore. If you did not enable delete_temp_files=True in configure_and_preview, you can do it manually.
Note on Analysis Files: In FutureWeatherGenerator v4 (Global) and v2 (Europe), the tool generates several analysis folders (e.g., 00_logs, 01_processing_transcripts, etc.) when enabled. These folders are not moved to the final output directory; they remain in the temporary directory for inspection. If you delete the temporary directory, these files will be lost.
[19]:
import shutil
import os
# Clean up the results folders
for folder in ['./morphing_temp_results', './morphing_temp_results_europe', './results_hybrid', './results_using_excel', './00_logs']:
if os.path.exists(folder):
shutil.rmtree(folder)
print(f"Deleted: {folder}")
Deleted: ./morphing_temp_results
Deleted: ./results_hybrid
Deleted: ./results_using_excel
Deleted: ./00_logs
[ ]: