diff --git a/update_eplus_compare/AutomateVersionTranslation.ipynb b/update_eplus_compare/AutomateVersionTranslation.ipynb
index d25849d3..9ea82573 100644
--- a/update_eplus_compare/AutomateVersionTranslation.ipynb
+++ b/update_eplus_compare/AutomateVersionTranslation.ipynb
@@ -5,7 +5,7 @@
"metadata": {},
"source": [
"
\n",
- " Transition from E+ 23.2.0 to E+ 24.1.0
\n",
+ " Transition from E+ 24.1.0 to E+ 24.2.0\n",
"\n",
"
\n",
"\n",
@@ -64,11 +64,13 @@
"import matplotlib.pyplot as plt\n",
"import seaborn as sns\n",
"import re\n",
+ "import tempfile\n",
"\n",
"#import csv\n",
"import glob as gb\n",
"\n",
- "#import pathlib\n",
+ "from pathlib import Path\n",
+ "from typing import Optional\n",
"\n",
"import datetime\n",
"import sqlite3\n",
@@ -79,7 +81,6 @@
"\n",
"#import tqdm\n",
"from tqdm.notebook import trange, tqdm\n",
- "import pathlib\n",
"\n",
"from ipywidgets import HTML\n",
"from IPython.display import display\n",
@@ -107,7 +108,7 @@
"metadata": {},
"outputs": [],
"source": [
- "IDF_DIR = os.getcwd()\n",
+ "IDF_DIR = Path('.').absolute()\n",
"IDF_DIR"
]
},
@@ -118,39 +119,36 @@
"outputs": [],
"source": [
"# Path to the OpenStudio-resources/testruns/ directory\n",
- "# TESTRUNS_DIR = '/home/julien/Software/Others/OpenStudio-resources/testruns/'\n",
- "TESTRUNS_DIR = os.path.abspath('../testruns')\n",
- "OS_RES_DIR = os.path.abspath('..')\n",
+ "TESTRUNS_DIR = Path('../testruns').resolve()\n",
+ "OS_RES_DIR = Path('..').resolve()\n",
"\n",
- "EPLUS_OLD_VERSION = '23.2.0'\n",
- "OS_OLD_VERSION = '3.7.0'\n",
+ "EPLUS_OLD_VERSION = '24.1.0'\n",
+ "OS_OLD_VERSION = '3.8.0'\n",
"\n",
- "EPLUS_NEW_VERSION = '24.1.0'\n",
- "OS_NEW_VERSION = '3.8.0'\n",
+ "EPLUS_NEW_VERSION = '24.2.0'\n",
+ "OS_NEW_VERSION = '3.9.0' # This is really an alpha, with 24.2.0 upgrade...\n",
"\n",
"# Careful: We'll cd into the TRANSITION_CLI_DIR to run it, so it must be a writtable location...\n",
- "TRANSITION_CLI_DIR = '/home/julien/Software/Others/EnergyPlus-build-release-develop/Products'\n",
- "# For some reason this one doesn't work\n",
- "# TRANSITION_CLI_DIR = '/home/julien/Software/Others/OS-build2/EnergyPlus-8.9.0-1c5ba897d1-Linux-x86_64/EnergyPlus-8-9-0/PreProcess/IDFVersionUpdater/'\n",
- "# TRANSITION_CLI_DIR = '/home/julien/Software/Others/OS-build-release/EnergyPlus-24.1.0-9d7789a3ac-Linux-Ubuntu20.04-x86_64/PreProcess/IDFVersionUpdater'\n",
+ "TRANSITION_CLI_DIR = Path('~/Software/Others/EnergyPlus-build-release-develop/Products').expanduser()\n",
+ "# TRANSITION_CLI_DIR = Path('~/Software/Others/OS-build-release/EnergyPlus-24.1.0-9d7789a3ac-Linux-Ubuntu20.04-x86_64/PreProcess/IDFVersionUpdater').expanduser()\n",
"\n",
"# Force a given number of parallel process \n",
"# (defaults to nproc - 2, leaving one physical core free if you have hyperthreading)\n",
"N = None\n",
- "WEATHER_FILE= os.path.abspath(os.path.join(IDF_DIR, '../weatherdata/USA_IL_Chicago-OHare.Intl.AP.725300_TMY3.epw'))\n",
+ "WEATHER_FILE= (IDF_DIR / '../weatherdata/USA_IL_Chicago-OHare.Intl.AP.725300_TMY3.epw').resolve()\n",
"\n",
"# Path to EnergyPlus application & idd \n",
- "OLD_EPLUS_EXE = '/usr/local/EnergyPlus-23-2-0/energyplus'\n",
+ "OLD_EPLUS_EXE = Path('/usr/local/EnergyPlus-24-1-0/energyplus')\n",
+ "\n",
"# NEW_EPLUS_EXE = os.path.join(TRANSITION_CLI_DIR, 'energyplus-9.2.0')\n",
- "NEW_EPLUS_EXE = '/usr/local/EnergyPlus-24-1-0/energyplus'\n",
+ "NEW_EPLUS_EXE = Path('/usr/local/EnergyPlus-24-2-0/energyplus')\n",
"# NEW_EPLUS_EXE = '/home/julien/Software/Others/EnergyPlus-build-release-develop/Products/energyplus'\n",
"# NEW_EPLUS_EXE = '/home/julien/Software/Others/OS-build2/EnergyPlus-8.9.0-1c5ba897d1-Linux-x86_64/EnergyPlus-8-9-0/energyplus-8.9.0'\n",
"# NEW_EPLUS_EXE = '/home/julien/Downloads/Temp/EnergyPlus-23.1.0-ff86a13c18-Linux-Ubuntu20.04-x86_64/energyplus'\n",
"\n",
"# Path to OpenStudio CLIs\n",
- "OLD_OS_CLI = '/usr/local/openstudio-3.7.0/bin/openstudio'\n",
- "NEW_OS_CLI = '/usr/local/openstudio-3.8.0/bin/openstudio'\n",
- "# NEW_OS_CLI = '/home/julien/Software/Others/OS-build-release/Products/openstudio'\n",
+ "OLD_OS_CLI = Path('/usr/local/openstudio-3.8.0/bin/openstudio')\n",
+ "NEW_OS_CLI = Path('~/Software/Others/OS-build-release/Products/openstudio').expanduser()\n",
"# OLD_IDD_FILE = '/usr/local/EnergyPlus-8-8-0/Energy+.idd'\n",
"# NEW_IDD_FILE = os.path.join(TRANSITION_DIR, 'Energy+.idd')\n",
"\n",
@@ -159,6 +157,21 @@
"REGRESSION_TEST_FILTER = None"
]
},
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "assert TRANSITION_CLI_DIR.is_dir()\n",
+ "assert WEATHER_FILE.is_file()\n",
+ "\n",
+ "assert OLD_EPLUS_EXE.exists()\n",
+ "assert OLD_EPLUS_EXE.exists()\n",
+ "assert OLD_OS_CLI.exists()\n",
+ "assert NEW_OS_CLI.exists()"
+ ]
+ },
{
"cell_type": "markdown",
"metadata": {},
@@ -166,6 +179,16 @@
"## Setup"
]
},
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "ep_old_v_dashed = EPLUS_OLD_VERSION.replace('.', '-')\n",
+ "ep_new_v_dashed = EPLUS_NEW_VERSION.replace('.', '-')"
+ ]
+ },
{
"cell_type": "code",
"execution_count": null,
@@ -174,21 +197,33 @@
"source": [
"# For the translation to work,\n",
"# you'll have to chdir to the Transition CLI's folder\n",
- "TRANSITION_CLI = os.path.abspath(os.path.join(TRANSITION_CLI_DIR,\n",
- " 'Transition-V{}-to-V{}'.format(EPLUS_OLD_VERSION.replace('.', '-'),\n",
- " EPLUS_NEW_VERSION.replace('.', '-'))))\n",
+ "TRANSITION_CLI = TRANSITION_CLI_DIR / f\"Transition-V{ep_old_v_dashed}-to-V{ep_new_v_dashed}\"\n",
+ "assert TRANSITION_CLI.is_file()\n",
+ "\n",
+ "OLD_IDD_FILE = TRANSITION_CLI_DIR / f\"V{ep_old_v_dashed}-Energy+.idd\"\n",
+ "NEW_IDD_FILE = TRANSITION_CLI_DIR / f\"V{ep_new_v_dashed}-Energy+.idd\"\n",
+ "assert OLD_IDD_FILE.is_file()\n",
+ "assert NEW_IDD_FILE.is_file()\n",
+ "\n",
+ "TRANSITION_REPORT_VAR_PATH = TRANSITION_CLI_DIR / f\"Report Variables {ep_old_v_dashed} to {ep_new_v_dashed}.csv\"\n",
+ "if TRANSITION_REPORT_VAR_PATH.is_file():\n",
+ " print(f\"Found {TRANSITION_REPORT_VAR_PATH}\")\n",
+ "\n",
"# TODO: Temp override\n",
- "# TRANSITION_CLI = '/home/julien/Software/Others/EnergyPlus-build-release-develop/Products/Transition-V9-5-0-to-V9-6-0'\n",
+ "# TRANSITION_CLI = Path('/home/julien/Software/Others/EnergyPlus-build-release-develop/Products/Transition-V9-5-0-to-V9-6-0')\n",
"TRANSITION_CLI"
]
},
{
- "cell_type": "raw",
+ "cell_type": "code",
+ "execution_count": null,
"metadata": {},
+ "outputs": [],
"source": [
- "import psutil\n",
- "physical_cpus = psutil.cpu_count(logical=False)\n",
- "multiprocessing.cpu_count() * (physical_cpus - 1) / physical_cpus"
+ "if False:\n",
+ " import psutil\n",
+ " physical_cpus = psutil.cpu_count(logical=False)\n",
+ " multiprocessing.cpu_count() * (physical_cpus - 1) / physical_cpus"
]
},
{
@@ -203,6 +238,13 @@
" print(\"Defaulting number of processes to {}\".format(N))"
]
},
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": []
+ },
{
"cell_type": "code",
"execution_count": null,
@@ -210,19 +252,16 @@
"outputs": [],
"source": [
"# Create directories\n",
- "OLD_OS_DIR = \"{o}-{e}\".format(e=EPLUS_OLD_VERSION, o=OS_OLD_VERSION)\n",
- "OLD_OS_DIR = os.path.join(IDF_DIR, OLD_OS_DIR)\n",
+ "OLD_OS_DIR = IDF_DIR / f\"{OS_OLD_VERSION}-{EPLUS_OLD_VERSION}\"\n",
"\n",
- "NEW_OS_DIR = \"{o}-{e}\".format(e=EPLUS_NEW_VERSION, o=OS_NEW_VERSION)\n",
- "NEW_OS_DIR = os.path.join(IDF_DIR, NEW_OS_DIR)\n",
+ "NEW_OS_DIR = IDF_DIR / f\"{OS_NEW_VERSION}-{EPLUS_NEW_VERSION}\"\n",
"\n",
- "TRANSITION_DIR = \"Transition-{e}\".format(e=EPLUS_NEW_VERSION)\n",
- "TRANSITION_DIR = os.path.join(IDF_DIR, TRANSITION_DIR)\n",
+ "TRANSITION_DIR = IDF_DIR / f\"Transition-{EPLUS_NEW_VERSION}\"\n",
"\n",
"for p in [OLD_OS_DIR, NEW_OS_DIR, TRANSITION_DIR]:\n",
- " if not os.path.exists(p):\n",
- " os.makedirs(p)\n",
- " print('Creating directory: {}'.format(p))"
+ " if not p.is_dir():\n",
+ " p.mkdir(parents=True)\n",
+ " print(f\"Creating directory: {p}\")"
]
},
{
@@ -245,6 +284,19 @@
" 'DIR': TRANSITION_DIR}"
]
},
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def stringify_cmd(cmd) -> list[str]:\n",
+ " \"\"\"Takes a list of arguments that may be Path or str or int and turns into a List[str].\n",
+ " So that is it suitable to pass to subprocess.\n",
+ " \"\"\"\n",
+ " return list(map(str, cmd))"
+ ]
+ },
{
"cell_type": "markdown",
"metadata": {},
@@ -281,7 +333,7 @@
"outputs": [],
"source": [
"# Delete all testruns to ensure we don't end up grabbing the idf and sql from another version\n",
- "if os.path.exists(TESTRUNS_DIR):\n",
+ "if TESTRUNS_DIR.is_dir():\n",
" shutil.rmtree(TESTRUNS_DIR)"
]
},
@@ -312,10 +364,8 @@
]
},
{
- "cell_type": "code",
- "execution_count": null,
+ "cell_type": "raw",
"metadata": {},
- "outputs": [],
"source": [
"c_args = shlex.split(command)\n",
"\n",
@@ -380,15 +430,16 @@
"outputs": [],
"source": [
"found_idfs = []\n",
- "for f in gb.iglob(os.path.join(TESTRUNS_DIR, '**/*/in.idf')):\n",
- " f2 = os.path.relpath(f, TESTRUNS_DIR)\n",
+ "for f in TESTRUNS_DIR.glob('**/*/in.idf'):\n",
+ " f2 = f.relative_to(TESTRUNS_DIR)\n",
" \n",
- " test_name = os.path.split(os.path.split(f2)[0])[0]\n",
+ " test_name = f2.parts[0]\n",
" #print(test_name)\n",
- " dst_path = os.path.join(IDF_DIR, \"{}.idf\".format(test_name))\n",
+ " dst_path = IDF_DIR / f\"{test_name}.idf\"\n",
" shutil.copyfile(f, dst_path)\n",
" found_idfs.append(test_name)\n",
- "found_idfs = set(found_idfs)"
+ "found_idfs = set(found_idfs)\n",
+ "len(found_idfs)"
]
},
{
@@ -404,16 +455,16 @@
"metadata": {},
"outputs": [],
"source": [
- "found_sqls = []\n",
- "\n",
- "for f in gb.iglob(os.path.join(TESTRUNS_DIR, '**/*/*.sql')):\n",
- " f2 = os.path.relpath(f, TESTRUNS_DIR)\n",
- " test_name = os.path.split(os.path.split(f2)[0])[0]\n",
+ "for f in TESTRUNS_DIR.glob(\"**/*/*.sql\"):\n",
+ " f2 = f.relative_to(TESTRUNS_DIR)\n",
+ " \n",
+ " test_name = f2.parts[0]\n",
" # print(test_name)\n",
- " dst_folder = os.path.join(OLD_OS_DIR, test_name)\n",
- " if not os.path.exists(dst_folder):\n",
- " os.makedirs(dst_folder)\n",
- " dst_path = os.path.join(dst_folder, \"eplusout.sql\")\n",
+ " dst_folder = OLD_OS_DIR / test_name\n",
+ " if not dst_folder.is_dir():\n",
+ " dst_folder.mkdir(parents=False, exist_ok=False)\n",
+ " \n",
+ " dst_path = dst_folder / \"eplusout.sql\"\n",
" # print(dst_path)\n",
" shutil.copyfile(f, dst_path)\n",
" found_sqls.append(test_name)\n",
@@ -462,7 +513,57 @@
"metadata": {},
"outputs": [],
"source": [
- "def translate_file(path):\n",
+ "def _prepare_temp_dir_for_transition() -> Path:\n",
+ " temp_dir = Path(tempfile.mkdtemp(prefix='transition-'))\n",
+ " shutil.copy(OLD_IDD_FILE, temp_dir)\n",
+ " shutil.copy(NEW_IDD_FILE, temp_dir)\n",
+ " if TRANSITION_REPORT_VAR_PATH.is_file():\n",
+ " shutil.copy(TRANSITION_REPORT_VAR_PATH, temp_dir)\n",
+ " return temp_dir\n",
+ "\n",
+ "def translate_file_parallelizable(idf_path: Path):\n",
+ " assert idf_path.is_file(), f\"Could not find {idf_path}\"\n",
+ " \n",
+ " temp_dir = _prepare_temp_dir_for_transition()\n",
+ " cmd = stringify_cmd([TRANSITION_CLI, idf_path])\n",
+ " r = subprocess.run(\n",
+ " cmd,\n",
+ " capture_output=True,\n",
+ " shell=False,\n",
+ " encoding='utf-8',\n",
+ " cwd=temp_dir,\n",
+ " )\n",
+ " \n",
+ " if r.returncode == 0: \n",
+ " # Move the resulting IDF into the new dir\n",
+ " new_file = idf_path.with_suffix('.idfnew')\n",
+ " assert new_file.is_file(), f\"Could not find {new_file}\"\n",
+ " new_dest = TRANSITION_DIR / idf_path.name\n",
+ " shutil.move(new_file, new_dest)\n",
+ "\n",
+ " # Move the old version into its directory\n",
+ " old_file = idf_path.with_suffix('.idfold')\n",
+ " assert old_file.is_file(), f\"Could not find {old_file}\"\n",
+ " old_dest = OLD_OS_DIR / idf_path.name\n",
+ " shutil.move(old_file, old_dest)\n",
+ "\n",
+ " # Delete original file\n",
+ " idf_path.unlink()\n",
+ "\n",
+ " # print('Done for {}.idf - {}'.format(eplus_file, path))\n",
+ " else:\n",
+ " print(f\"Error for {idf_path}:\")\n",
+ " print(r.stdout)\n",
+ " print(r.stderr)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def translate_file_regular_serially(path):\n",
" \"\"\"\n",
" Runs the file throught the transition utility and save in the right folder\n",
" Will move the ori file to the subdirectory OLD_DIR (eg `./8.8.0/`)\n",
@@ -471,7 +572,8 @@
" \n",
" eplus_file, ext = os.path.splitext(os.path.split(path)[1])\n",
" \n",
- " process = subprocess.Popen([TRANSITION_CLI, path],\n",
+ " cmd = stringify_cmd([TRANSITION_CLI, path])\n",
+ " process = subprocess.Popen(cmd,\n",
" shell=False,\n",
" stdout=subprocess.PIPE,\n",
" stderr=subprocess.PIPE)\n",
@@ -506,7 +608,7 @@
"metadata": {},
"outputs": [],
"source": [
- "files = [os.path.abspath(file) for file in gb.glob(os.path.join(IDF_DIR, '*.idf'))]\n",
+ "files = list(IDF_DIR.glob('*.idf'))\n",
"len(files)"
]
},
@@ -516,14 +618,17 @@
"metadata": {},
"outputs": [],
"source": [
- "files"
+ "# for x in problems.index[problems[next(x for x in problems.columns if x[1] == 'Transition')].isna()]:\n",
+ "# shutil.copy(f\"{OLD_OS_DIR}/{x}.idf\", f\"{IDF_DIR}/{x}.idf\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
- "**Transitionning in parallel seems to fail, so do it serially...**"
+ "**Transitionning in parallel seems to fail, so do it serially...**\n",
+ "\n",
+ "**Edit**: I made it work by using a temporary directory"
]
},
{
@@ -532,21 +637,15 @@
"metadata": {},
"outputs": [],
"source": [
- "if False:\n",
- " # You must cd to the Transition CLI's folder for it to work\n",
- " os.chdir(TRANSITION_CLI_DIR)\n",
- "\n",
+ "if True:\n",
" # Takes about 10minutes on my machine with 12 threads allocated\n",
- " pool = multiprocessing.Pool(processes=12)\n",
+ " pool = multiprocessing.Pool(processes=N)\n",
"\n",
- " desc = 'Translation from {} to {}
'.format(EPLUS_OLD_VERSION,\n",
- " EPLUS_NEW_VERSION)\n",
+ " desc = f'Translation from {EPLUS_OLD_VERSION} to {EPLUS_NEW_VERSION}
'\n",
" label = HTML(desc)\n",
" display(label)\n",
- " for _ in tqdm(pool.imap_unordered(translate_file, files), total=len(files)):\n",
- " pass\n",
- "\n",
- " os.chdir(IDF_DIR)"
+ " for _ in tqdm(pool.imap_unordered(translate_file_parallelizable, files), total=len(files)):\n",
+ " pass"
]
},
{
@@ -555,15 +654,16 @@
"metadata": {},
"outputs": [],
"source": [
- "os.chdir(TRANSITION_CLI_DIR)\n",
+ "if False:\n",
+ " os.chdir(TRANSITION_CLI_DIR)\n",
"\n",
- "desc = 'Translation from {} to {}
'.format(EPLUS_OLD_VERSION,\n",
- " EPLUS_NEW_VERSION)\n",
- "label = HTML(desc)\n",
- "for file in tqdm(files):\n",
- " translate_file(file)\n",
- " \n",
- "os.chdir(IDF_DIR)"
+ " desc = 'Translation from {} to {}
'.format(EPLUS_OLD_VERSION,\n",
+ " EPLUS_NEW_VERSION)\n",
+ " label = HTML(desc)\n",
+ " for file in tqdm(files):\n",
+ " translate_file_regular_serially(file)\n",
+ "\n",
+ " os.chdir(IDF_DIR)"
]
},
{
@@ -574,9 +674,9 @@
"source": [
"# At this point, you shouldn't have any .idf files in the IDF_DIR directory\n",
"# If you do, means that the transition failed\n",
- "all_files = gb.glob(os.path.join(IDF_DIR, '*.idf'))\n",
- "all_files += gb.glob(os.path.join(IDF_DIR, '*.idfnew'))\n",
- "all_files += gb.glob(os.path.join(IDF_DIR, '*.idfold'))\n",
+ "all_files = []\n",
+ "for e in ['idf', 'idfnew', 'idfold']:\n",
+ " all_files += list(IDF_DIR.glob(f'*.{e}'))\n",
"\n",
"all_files"
]
@@ -793,8 +893,8 @@
"SQL_QUERY_SIM_INFO = 'SELECT EnergyPlusVersion FROM Simulations'\n",
"\n",
"VERSION_REGEX = re.compile(r'Version (?P\\d+)\\.(?P\\d+)\\.'\n",
- " '(?P\\d+)-(?P\\w+),\\s+'\n",
- " 'YMD=(?P[0-9\\.: ]+)')\n",
+ " r'(?P\\d+)-(?P\\w+),\\s+'\n",
+ " r'YMD=(?P[0-9\\.: ]+)')\n",
"\n",
"\n",
"# Remove all files in the output directory except these\n",
@@ -807,7 +907,7 @@
"metadata": {},
"outputs": [],
"source": [
- "def parse_sql_version_and_sitekbtu(output_directory):\n",
+ "def parse_sql_version_and_sitekbtu(output_directory: Path) -> Optional[pd.Series]:\n",
" \"\"\"\n",
" This function grabs the EnergyPlusVersion and the total site energy\n",
" from the SQL file.\n",
@@ -823,15 +923,14 @@
" (or None if it didn't run), which name is the test_name\n",
" (gotten from the name of the output_directory)\n",
" \"\"\"\n",
- " sql_files = gb.glob(os.path.join(output_directory, \"*.sql\"))\n",
+ " sql_files = list(Path(output_directory).absolute().glob(\"*.sql\"))\n",
"\n",
" version_with_sha = None\n",
" site_kbtu = None\n",
"\n",
" if len(sql_files) == 1:\n",
" sql_path = sql_files[0]\n",
- " abs_sql_path = os.path.abspath(sql_path)\n",
- " sql_uri = '{}?mode=ro'.format(pathlib.Path(abs_sql_path).as_uri())\n",
+ " sql_uri = f\"{sql_path.as_uri()}?mode=ro\"\n",
" with sqlite3.connect(sql_uri, uri=True) as con:\n",
" cursor = con.cursor()\n",
" r = cursor.execute(SQL_QUERY_SIM_INFO).fetchone()\n",
@@ -841,9 +940,9 @@
" if m:\n",
" gpdict = m.groupdict()\n",
" version_with_sha = \"{}.{}.{}-{}\".format(gpdict['Major'],\n",
- " gpdict['Minor'],\n",
- " gpdict['Patch'],\n",
- " gpdict['SHA'])\n",
+ " gpdict['Minor'],\n",
+ " gpdict['Patch'],\n",
+ " gpdict['SHA'])\n",
" else:\n",
" msg = (\"Cannot find the EnergyPlusVersion in the SQL file. \"\n",
" \"For:\\n{}\".format(output_directory))\n",
@@ -868,58 +967,24 @@
"metadata": {},
"outputs": [],
"source": [
- "def run_OLD_eplus_sim(eplus_file):\n",
- " \"\"\"\n",
- " Runs the simulation with OLD_EPLUS_EXE and calls parse_sql\n",
- " \"\"\"\n",
- " base, file_with_ext = os.path.split(os.path.abspath(eplus_file))\n",
- " output_directory = os.path.join(base, os.path.splitext(file_with_ext)[0])\n",
- " # If directory exists, delete it\n",
- " if os.path.exists(output_directory):\n",
- " shutil.rmtree(output_directory)\n",
- " # Recreate it\n",
- " os.makedirs(output_directory)\n",
+ "def run_eplus_sim(\n",
+ " eplus_file: Path, ep_cli: Path,\n",
+ " expand_objects: bool = False,\n",
+ " verbose: bool = False\n",
+ ") -> pd.Series:\n",
+ " eplus_file = Path(eplus_file).absolute()\n",
+ " assert eplus_file.is_file(), f\"Could not find {eplus_file}\"\n",
" \n",
- " process = subprocess.Popen([OLD_EPLUS_EXE,\n",
- " # '-i', OLD_IDD_FILE\n",
- " '-w', WEATHER_FILE,\n",
- " '-d', output_directory,\n",
- " eplus_file],\n",
- " stdout=subprocess.PIPE,\n",
- " stderr=subprocess.PIPE,\n",
- " universal_newlines=True, \n",
- " shell=False)\n",
- " \n",
- " # wait for the process to terminate\n",
- " out, err = process.communicate()\n",
- " errcode = process.returncode\n",
- " if errcode == 0:\n",
- " # Clean up output directory\n",
- " [os.remove(x) for x in gb.glob(os.path.join(output_directory, '*'))\n",
- " if os.path.splitext(x)[1] not in KEEP_EXT]\n",
- " return parse_sql_version_and_sitekbtu(output_directory)\n",
- " else:\n",
- " print(\"ERROR: {}\".format(eplus_file))\n",
- " print(out)\n",
- " print(err)\n",
- " return pd.Series([None, None],\n",
- " index=['E+', 'SiteKBTU'],\n",
- " name = os.path.split(output_directory)[1])\n",
- " \n",
- "def run_NEW_eplus_sim(eplus_file, expand_objects=False):\n",
- " \"\"\"\n",
- " Runs the simulation with NEW_EPLUS_EXE and calls parse_sql\n",
- " \"\"\"\n",
- " base, file_with_ext = os.path.split(os.path.abspath(eplus_file))\n",
- " output_directory = os.path.join(base, os.path.splitext(file_with_ext)[0])\n",
+ " output_directory = eplus_file.parent / eplus_file.stem\n",
" # If directory exists, delete it\n",
- " if os.path.exists(output_directory):\n",
+ " if output_directory.is_dir():\n",
" shutil.rmtree(output_directory)\n",
+ " \n",
" # Recreate it\n",
- " os.makedirs(output_directory)\n",
+ " output_directory.mkdir(parents=True, exist_ok=False)\n",
" \n",
" cmd = [\n",
- " NEW_EPLUS_EXE\n",
+ " ep_cli\n",
" ]\n",
" if expand_objects:\n",
" cmd.append('-x')\n",
@@ -929,40 +994,57 @@
" '-d', output_directory,\n",
" eplus_file\n",
" ]\n",
- " # print(f\"cmd={' '.join(cmd)}\\n\")\n",
- " process = subprocess.Popen(cmd,\n",
- " stdout=subprocess.PIPE,\n",
- " stderr=subprocess.PIPE,\n",
- " universal_newlines=True, \n",
- " shell=False)\n",
- " \n",
- " # wait for the process to terminate\n",
- " out, err = process.communicate()\n",
- " errcode = process.returncode\n",
- " if errcode == 0:\n",
+ " cmd = stringify_cmd(cmd)\n",
+ " if verbose:\n",
+ " print(\" \".join(cmd))\n",
+ " r = subprocess.run(\n",
+ " cmd,\n",
+ " capture_output=True,\n",
+ " shell=False,\n",
+ " encoding='utf-8',\n",
+ " )\n",
+ " \n",
+ " if r.returncode == 0: \n",
" # Clean up output directory\n",
- " [os.remove(x) for x in gb.glob(os.path.join(output_directory, '*'))\n",
- " if os.path.splitext(x)[1] not in KEEP_EXT]\n",
+ " [\n",
+ " x.unlink() for x in output_directory.glob('*') \n",
+ " if x.suffix not in KEEP_EXT\n",
+ " ]\n",
" return parse_sql_version_and_sitekbtu(output_directory)\n",
" else:\n",
- " print(\"ERROR: {}\".format(eplus_file))\n",
- " # print(out)\n",
- " # print(err)\n",
+ " print(f\"ERROR with code {r.returncode}: {eplus_file}\")\n",
+ " # print(r.stdout)\n",
+ " # print(r.stderr)\n",
" return pd.Series([None, None],\n",
" index=['E+', 'SiteKBTU'],\n",
- " name = os.path.split(output_directory)[1])"
+ " name = os.path.split(output_directory)[1])\n",
+ "\n",
+ "def run_OLD_eplus_sim(eplus_file: Path, expand_objects: bool = False, verbose: bool = False):\n",
+ " \"\"\"\n",
+ " Runs the simulation with OLD_EPLUS_EXE and calls parse_sql\n",
+ " \"\"\"\n",
+ " return run_eplus_sim(eplus_file=eplus_file, ep_cli=OLD_EPLUS_EXE,\n",
+ " expand_objects=expand_objects, verbose=verbose)\n",
+ "\n",
+ " \n",
+ "def run_NEW_eplus_sim(eplus_file: Path, expand_objects: bool = False, verbose: bool = False) -> pd.Series:\n",
+ " \"\"\"\n",
+ " Runs the simulation with NEW_EPLUS_EXE and calls parse_sql\n",
+ " \"\"\"\n",
+ " return run_eplus_sim(eplus_file=eplus_file, ep_cli=NEW_EPLUS_EXE,\n",
+ " expand_objects=expand_objects, verbose=verbose)"
]
},
{
- "cell_type": "markdown",
+ "cell_type": "code",
+ "execution_count": null,
"metadata": {},
+ "outputs": [],
"source": [
- "```\n",
"# Test one sim\n",
- "files = gb.glob(os.path.join(TRANSITION_DIR, '*.idf'))\n",
- "eplus_file = files[0]\n",
- "run_NEW_eplus_sim(eplus_file)\n",
- "```"
+ "if False: \n",
+ " eplus_file = next(TRANSITION_DIR.glob('*.idf'))\n",
+ " run_NEW_eplus_sim(eplus_file)"
]
},
{
@@ -985,7 +1067,7 @@
"outputs": [],
"source": [
"if False:\n",
- " files = gb.glob(os.path.join(OLD_DIR, '*.idf'))\n",
+ " files = list(OLD_DIR.glob(\"*.idf\"))\n",
"\n",
" pool = multiprocessing.Pool(processes=N)\n",
"\n",
@@ -1137,7 +1219,7 @@
]
},
{
- "cell_type": "markdown",
+ "cell_type": "raw",
"metadata": {},
"source": [
"```\n",
@@ -1166,8 +1248,10 @@
]
},
{
- "cell_type": "raw",
+ "cell_type": "code",
+ "execution_count": null,
"metadata": {},
+ "outputs": [],
"source": [
"# If you ever send a Keyboard Interrupt signal to kill the above cell\n",
"# (via Kernel > Interrupt), you need to run this too\n",
@@ -1253,7 +1337,7 @@
"# Delete all testruns to ensure we don't end up grabbing the idf and sql from another version\n",
"# model_tests.rb only cleans out testruns/testXXX directories for tests we do request\n",
"# So if you use a regression test filter, you could have left overs\n",
- "if os.path.exists(TESTRUNS_DIR):\n",
+ "if TESTRUNS_DIR.is_dir():\n",
" shutil.rmtree(TESTRUNS_DIR)"
]
},
@@ -1332,15 +1416,6 @@
"TESTRUNS_DIR, NEW_OS_DIR"
]
},
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "len(sorted(list(gb.iglob(os.path.join(TESTRUNS_DIR, '**/*/in.idf')))))"
- ]
- },
{
"cell_type": "code",
"execution_count": null,
@@ -1348,12 +1423,12 @@
"outputs": [],
"source": [
"found_idfs = []\n",
- "for f in gb.iglob(os.path.join(TESTRUNS_DIR, '**/*/in.idf')):\n",
- " f2 = os.path.relpath(f, TESTRUNS_DIR)\n",
+ "for f in TESTRUNS_DIR.glob('**/*/in.idf'):\n",
+ " f2 = f.relative_to(TESTRUNS_DIR)\n",
" \n",
- " test_name = os.path.split(os.path.split(f2)[0])[0]\n",
+ " test_name = f2.parts[0]\n",
" #print(test_name)\n",
- " dst_path = os.path.join(NEW_OS_DIR, \"{}.idf\".format(test_name))\n",
+ " dst_path = NEW_OS_DIR / f\"{test_name}.idf\"\n",
" shutil.copyfile(f, dst_path)\n",
" found_idfs.append(test_name)\n",
"found_idfs = set(found_idfs)\n",
@@ -1384,15 +1459,16 @@
"source": [
"found_sqls = []\n",
"\n",
- "for f in gb.iglob(os.path.join(TESTRUNS_DIR, '**/*/*.sql')):\n",
- " f2 = os.path.relpath(f, TESTRUNS_DIR)\n",
+ "for f in TESTRUNS_DIR.glob(\"**/*/*.sql\"):\n",
+ " f2 = f.relative_to(TESTRUNS_DIR)\n",
" \n",
- " test_name = os.path.split(os.path.split(f2)[0])[0]\n",
+ " test_name = f2.parts[0]\n",
" # print(test_name)\n",
- " dst_folder = os.path.join(NEW_OS_DIR, test_name)\n",
- " if not os.path.exists(dst_folder):\n",
- " os.makedirs(dst_folder)\n",
- " dst_path = os.path.join(dst_folder, \"eplusout.sql\")\n",
+ " dst_folder = NEW_OS_DIR / test_name\n",
+ " if not dst_folder.is_dir():\n",
+ " dst_folder.mkdir(parents=False, exist_ok=False)\n",
+ " \n",
+ " dst_path = dst_folder / \"eplusout.sql\"\n",
" # print(dst_path)\n",
" shutil.copyfile(f, dst_path)\n",
" found_sqls.append(test_name)\n",
@@ -1477,9 +1553,9 @@
"\"\"\"\n",
"\n",
"TIME_REGEX = re.compile(r'.* Elapsed Time=(?P\\d+)hr *(?P\\d+)min'\n",
- " ' *(?P[\\d\\.]+)sec')\n",
+ " r' *(?P[\\d\\.]+)sec')\n",
"\n",
- "def parse_sql_runtime(output_directory):\n",
+ "def parse_sql_runtime(output_directory: Path):\n",
" \"\"\"\n",
" This function grabs the E+ runtime from the SQL file.\n",
" \n",
@@ -1492,14 +1568,13 @@
" ---------\n",
" * runtime (datetime.time)\n",
" \"\"\"\n",
+ " output_directory = Path(output_directory).absolute()\n",
+ " sql_files = list(output_directory.glob(\"*.sql\"))\n",
" \n",
- " sql_files = gb.glob(os.path.join(output_directory, \"*.sql\"))\n",
- "\n",
" runtime = None\n",
" if len(sql_files) == 1:\n",
" sql_path = sql_files[0]\n",
- " abs_sql_path = os.path.abspath(sql_path)\n",
- " sql_uri = '{}?mode=ro'.format(pathlib.Path(abs_sql_path).as_uri())\n",
+ " sql_uri = f'{sql_path.as_uri()}?mode=ro'\n",
" with sqlite3.connect(sql_uri, uri=True) as con:\n",
" cursor = con.cursor()\n",
" r = cursor.execute(SQL_QUERY_RUNTIME).fetchone()\n",
@@ -1524,7 +1599,7 @@
" #raise ValueError(msg)\n",
" print(msg)\n",
" \n",
- " return [os.path.split(output_directory)[1], runtime]"
+ " return [output_directory.name, runtime]"
]
},
{
@@ -1808,7 +1883,9 @@
{
"cell_type": "code",
"execution_count": null,
- "metadata": {},
+ "metadata": {
+ "scrolled": false
+ },
"outputs": [],
"source": [
"def background_colors(val):\n",
@@ -1818,7 +1895,7 @@
" fmt = s.format('#F4C7C3')\n",
" return fmt\n",
"print(\"These are the files were we have some (but not all) failures\")\n",
- "problems.style.applymap(background_colors)"
+ "problems.style.map(background_colors)"
]
},
{
@@ -1834,8 +1911,28 @@
"metadata": {},
"outputs": [],
"source": [
- "# files = [f'{TRANSITION_DIR}/{x}.idf' for x in problems.index]\n",
- "# for f in files:\n",
+ "files = [f'{TRANSITION_DIR}/{x}.idf' for x\n",
+ " in problems.index[problems[next(x for x in problems.columns if x[1] == 'Transition')].isna()]]\n",
+ "len(files)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# ERROR: Could not find input data dictionary: /path/to/OpenStudio-resources/update_eplus_compare/Energy+.idd.\n",
+ "shutil.copy(OLD_EPLUS_EXE.parent / 'Energy+.idd', IDF_DIR)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# for f in tqdm(files):\n",
"# run_NEW_eplus_sim(f, expand_objects=True)\n",
" \n",
"# Reparse the SQLs above again"
@@ -1890,7 +1987,7 @@
},
"outputs": [],
"source": [
- "pct_threshold = 0.0001\n",
+ "pct_threshold = 0.001\n",
"print(\"Setting % diff threshold to {:.3%}\".format(pct_threshold))"
]
},
@@ -1987,6 +2084,88 @@
"plt.show()"
]
},
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "s_eplus = df_diff.iloc[:, 0]\n",
+ "s_eplus.index = pd.MultiIndex.from_tuples(s_eplus[s_eplus.abs() >= pct_threshold].index.str.split('.').tolist())"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "s_eplus = s_eplus.swaplevel(0, 1).loc['osm']\n",
+ "s_eplus.name = 'Diff from 24.1.0 to 24.2.0'"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "s_eplus.to_frame().style.format(\"{:.2%}\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "large_eplus_diffs = s_eplus.index.tolist()\n",
+ "large_eplus_diffs"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "temp_dir = IDF_DIR / 'large_eplus_diffs'\n",
+ "temp_dir.mkdir(parents=True, exist_ok=True)\n",
+ "for f in large_eplus_diffs:\n",
+ " old_idf = OLD_OS_DIR / f\"{f}.osm.idf\"\n",
+ " assert old_idf.is_file()\n",
+ " trans_idf = TRANSITION_DIR / f\"{f}.osm.idf\"\n",
+ " assert trans_idf.is_file()\n",
+ " shutil.copyfile(old_idf, temp_dir / f\"{f}.osm_{EPLUS_OLD_VERSION.replace('.', '_')}.idf\")\n",
+ " copied_new_idf = temp_dir / f\"{f}.osm_{EPLUS_NEW_VERSION.replace('.', '_')}.idf\"\n",
+ " shutil.copyfile(trans_idf, copied_new_idf)\n",
+ " \n",
+ " subprocess.check_output([\n",
+ " '/home/julien/Software/Others/OS-build-release/Products/openstudio',\n",
+ " '-e',\n",
+ " f\"w = OpenStudio::Workspace.load('{copied_new_idf}').get(); w.save('{copied_new_idf}', true)\"\n",
+ " ])\n",
+ " "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "EPLUS_NEW_VERSION.replace('.', '_')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "temp_dir"
+ ]
+ },
{
"cell_type": "markdown",
"metadata": {},
@@ -2299,8 +2478,8 @@
" columns = ['FuelType','Units']\n",
" \"\"\"\n",
"\n",
- " abs_sql_path = os.path.abspath(sql_path)\n",
- " sql_uri = '{}?mode=ro'.format(pathlib.Path(abs_sql_path).as_uri())\n",
+ " abs_sql_path = Path(sql_path).absolute()\n",
+ " sql_uri = '{}?mode=ro'.format(abs_sql_path.as_uri())\n",
" \n",
" # RowName = '#{end_use}'\n",
" # ColumnName='#{fuel_type}'\n",
@@ -3585,8 +3764,8 @@
" (gotten from the name of the output_directory)\n",
" \"\"\"\n",
"\n",
- " abs_sql_path = os.path.abspath(sql_path)\n",
- " sql_uri = '{}?mode=ro'.format(pathlib.Path(abs_sql_path).as_uri())\n",
+ " abs_sql_path = Path(sql_path).absolute()\n",
+ " sql_uri = '{}?mode=ro'.format(abs_sql_path.as_uri())\n",
" with sqlite3.connect(sql_uri, uri=True) as con:\n",
" cursor = con.cursor()\n",
" r = cursor.execute(SQL_QUERY_SIM_INFO).fetchone()\n",
@@ -3712,7 +3891,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
- "version": "3.9.7"
+ "version": "3.12.2"
},
"toc": {
"base_numbering": 1,