-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge remote-tracking branch 'j-bryan/teal' into inno_work
- Loading branch information
Showing
24 changed files
with
699 additions
and
17 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,3 +3,4 @@ install_requires = | |
raven-framework | ||
teal-ravenframework | ||
heron-ravenframework | ||
ipopt |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,21 +1,36 @@ | ||
import sys | ||
import platform | ||
import os | ||
from cx_Freeze import setup, Executable, build_exe | ||
|
||
import HERON.templates.write_inner | ||
|
||
|
||
build_exe_options = { | ||
"packages": ["ravenframework","msgpack","ray","crow_modules","AMSC","sklearn","pyomo","HERON"], | ||
"packages": ["ravenframework","msgpack","ray","crow_modules","AMSC","sklearn","pyomo","HERON","TEAL","pyarrow","netCDF4","cftime"], | ||
"includes": ["ray.thirdparty_files.colorama","ray.autoscaler._private","pyomo.common.plugins","HERON.templates.template_driver"], | ||
"include_files": [(HERON.templates.write_inner.__file__,"lib/HERON/templates/write_inner.py")], | ||
"include_msvcr": True, | ||
} | ||
|
||
# Some files must be included manually for the Windows build | ||
if platform.system().lower() == "windows": | ||
# netCDF4 .dll files get missed by cx_Freeze | ||
# ipopt executable must be included manually | ||
netCDF4_libs_path = os.path.join(os.path.dirname(sys.executable), "lib", "site-packages", "netCDF4.libs") | ||
build_exe_options["include_files"] += [ | ||
("Ipopt-3.14.13-win64-msvs2019-md/","local/bin/Ipopt-3.14.13-win64-msvs2019-md"), # FIXME: Point to the correct location for ipopt executable | ||
(netCDF4_libs_path,"lib/netCDF4") | ||
] | ||
# Include the Microsoft Visual C++ Runtime | ||
build_exe_options["include_msvcr"] = True | ||
|
||
|
||
setup( | ||
name="force", | ||
version="0.1", | ||
description="FORCE package", | ||
executables=[Executable(script="raven_framework.py",icon="raven_64.ico"), | ||
Executable(script="heron.py",icon="heron_64.ico")], | ||
Executable(script="heron.py",icon="heron_64.ico"), | ||
Executable(script="teal.py",icon="teal_64.ico")], | ||
options={"build_exe": build_exe_options}, | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
#!/usr/bin/env python | ||
# Copyright 2017 Battelle Energy Alliance, LLC | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
""" | ||
Created on Feb 8, 2024 | ||
@author: j-bryan (Jacob Bryan) | ||
Runs the TEAL package as a standalone application. | ||
""" | ||
import sys | ||
from TEAL.src.CashFlow_ExtMod import TEALmain | ||
from ui import run_from_gui | ||
|
||
|
||
if __name__ == '__main__': | ||
import argparse | ||
parser = argparse.ArgumentParser(description='RAVEN') | ||
parser.add_argument('-w', action='store_true', default=False, required=False,help='Run in the GUI') | ||
parser.add_argument('-iXML', nargs=1, required=False, help='XML CashFlow input file name', metavar='inp_file') | ||
parser.add_argument('-iINP', nargs=1, required=False, help='CashFlow input file name with the input variable list', metavar='inp_file') | ||
parser.add_argument('-o', nargs=1, required=False, help='Output file name', metavar='out_file') | ||
args = parser.parse_args() | ||
|
||
# Remove the -w argument from sys.argv so it doesn't interfere with TEAL's argument parsing | ||
if args.w: | ||
sys.argv.remove('-w') | ||
|
||
# If the -w argument is present or any of the other arguments are missing, run the GUI | ||
if args.w or not args.iXML or not args.iINP or not args.o: | ||
print('Running TEAL in GUI mode') | ||
run_from_gui(TEALmain) | ||
else: | ||
print('Running TEAL in command line mode') | ||
sys.exit(TEALmain()) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
from .main import run_from_gui |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
from .main import Controller |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
from typing import Optional | ||
import os | ||
import tkinter as tk | ||
import argparse | ||
from collections import namedtuple | ||
|
||
|
||
class FileSpec: | ||
""" Input/output file specification for a package. """ | ||
def __init__(self, | ||
arg_name: str, | ||
description: str, | ||
default_filename: Optional[str] = None, | ||
is_output: bool = False, | ||
file_type: Optional[str] = None): | ||
""" | ||
Constructor | ||
@In, arg_name, str, optional, the argument flag for the file | ||
@In, description, str, the description of the file | ||
@In, default_filename, str, optional, the default filename | ||
@In, is_output, bool, optional, whether the file is an output file | ||
@In, file_type, str, optional, the type of file | ||
@Out, None | ||
""" | ||
self.arg_name = arg_name | ||
self.description = description | ||
self.default_filename = default_filename | ||
self.is_output = is_output | ||
self.file_type = file_type | ||
|
||
def add_to_parser(self, parser: argparse.ArgumentParser) -> argparse.ArgumentParser: | ||
""" | ||
Adds the file specification to the parser. | ||
@In, parser, argparse.ArgumentParser, the parser | ||
@Out, parser, argparse.ArgumentParser, the parser with the file specification added | ||
""" | ||
if self.arg_name.startswith('-'): | ||
parser.add_argument(self.arg_name, nargs=1, required=False, default=self.default_filename, | ||
help=self.description) | ||
else: # positional argument | ||
parser.add_argument(self.arg_name, nargs='?', default=self.default_filename, help=self.description) | ||
return parser | ||
|
||
|
||
class FileSelectionController: | ||
""" Controller for the file selection widget. """ | ||
_file_selection_specs = { | ||
'teal': [FileSpec('-iXML', 'XML File', file_type='xml'), | ||
FileSpec('-iINP','CashFlow File'), | ||
FileSpec('-o', 'Output File', is_output=True)], | ||
'ravenframework': [FileSpec('filename', 'RAVEN XML File', file_type='xml')], | ||
'heron': [FileSpec('filename', 'HERON Input File', file_type='xml')] | ||
} | ||
|
||
def __init__(self, model, view): | ||
""" | ||
Constructor | ||
@In, model, Model, the model | ||
@In, view, FileSelection, the view | ||
@Out, None | ||
""" | ||
self.file_selection = view | ||
|
||
# Create the file selectors, adding any files specified from the command line | ||
model_package_name = model.get_package_name().strip().lower() | ||
self._file_specs = self._file_selection_specs[model_package_name] | ||
cli_args = self._parse_cli_args() | ||
for spec in self._file_specs: | ||
filename = cli_args.get(spec.arg_name, spec.default_filename) | ||
if isinstance(filename, (list, tuple)): # argparse returns items in a tuple sometimes | ||
filename = filename[0] | ||
self.file_selection.add_file_selector(spec.description, filename, spec.file_type, spec.is_output) | ||
|
||
def get_files(self): | ||
""" | ||
Gets the files selected by the user and returns them as a list along with their | ||
corresponding argument flags, if any. | ||
@In, None | ||
@Out, files, list, a list of files and their corresponding argument flags, if any | ||
""" | ||
files = [] | ||
for spec in self._file_specs: | ||
# Get the filename from the file selector | ||
filename = self.file_selection.file_selectors[spec.description].get_filename() | ||
# Add the filename with its corresponding argument flag to the list | ||
if not os.path.exists(filename) and spec.arg_name != '-o': | ||
raise FileNotFoundError(f"File {filename} not found") | ||
if spec.arg_name.startswith('-'): # flag argument | ||
files.extend([spec.arg_name, filename]) | ||
else: # positional argument | ||
files.append(filename) | ||
return files | ||
|
||
def _parse_cli_args(self) -> dict[str]: | ||
""" | ||
Parse arguments provided from the command line | ||
@In, None | ||
@Out, args, dict, the parsed arguments | ||
""" | ||
parser = argparse.ArgumentParser() | ||
for spec in self._file_specs: | ||
parser = spec.add_to_parser(parser) | ||
args = vars(parser.parse_args()) | ||
# Any arguments with flags will have had the '-' stripped off. It'll be helpful to know which | ||
# arguments were specified with flags, so we'll add the '-' back to the keys. | ||
for key in list(args.keys()): | ||
if f'-{key}' in [spec.arg_name for spec in self._file_specs]: | ||
args[f'-{key}'] = args.pop(key) | ||
return args |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import sys | ||
|
||
from .file_selection import FileSelectionController | ||
from .status import StatusController | ||
from .text_output import TextOutputController | ||
|
||
|
||
class Controller: | ||
def __init__(self, model, view): | ||
self.model = model | ||
self.view = view | ||
|
||
# Initialize controllers | ||
self.file_selection_controller = FileSelectionController(self.model, self.view.frames["file_selection"]) | ||
self.status_panel_controller = StatusController(self.model, self.view.frames["status_panel"]) | ||
self.text_output_controller = TextOutputController(self.model, self.view.frames["text_output"]) | ||
|
||
# Bind the run button to the model | ||
self.view.frames["run_abort"].run_button.config(command=self.run_model) | ||
# Bind the abort button to closing the window | ||
self.view.frames["run_abort"].abort_button.config(command=self.view.quit) | ||
|
||
# Bind Ctrl-C to closing the window for convenvience | ||
self.view.root.bind('<Control-c>', lambda cmd: self.view.root.destroy()) | ||
|
||
def run_model(self): | ||
# Construct sys.argv from the file selectors | ||
sys.argv = [sys.argv[0]] + self.file_selection_controller.get_files() | ||
print('sys.argv:', sys.argv) | ||
# Start the model | ||
self.model.start() | ||
# Status update loop | ||
self.view.frames["status_panel"].after(100, self.status_panel_controller.update_status) | ||
|
||
def start(self): | ||
self.view.mainloop() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import tkinter as tk | ||
import datetime | ||
|
||
|
||
class StatusController(tk.Frame): | ||
""" Controller for the status panel. """ | ||
def __init__(self, model, view): | ||
self.model = model | ||
self.view = view | ||
|
||
def set_status(self, status): | ||
self.view.status.set(f'Status: {status}') | ||
|
||
def set_timer(self, time): | ||
self.view.timer.set(f'Time: {time}') | ||
|
||
def update_status(self): | ||
self.set_status('Running' if self.model.is_alive() else 'Idle') | ||
time_elapsed = round(self.model.get_execution_time()) | ||
self.set_timer(f'{datetime.timedelta(seconds=time_elapsed)}') | ||
self.view.update() | ||
if self.model.is_alive(): | ||
self.view.after(100, self.update_status) | ||
else: | ||
self.set_status('Idle') |
Oops, something went wrong.