DTOcean Tidal Hydrodynamics + Database Example

Note, this example assumes the DTOcean database and the Hydroynamics Module has been installed


In [ ]:
%matplotlib inline

In [ ]:
from IPython.display import display, HTML

In [ ]:
import matplotlib.pyplot as plt
plt.rcParams['figure.figsize'] = (14.0, 8.0)

In [ ]:
import numpy as np

In [ ]:
from dtocean_core import start_logging
from dtocean_core.core import Core
from dtocean_core.menu import DataMenu, ModuleMenu, ProjectMenu
from dtocean_core.pipeline import Tree

In [ ]:
def html_list(x):
    message = "<ul>"
    for name in x:
        message += "<li>{}</li>".format(name)
    message += "</ul>"
    return message
def html_dict(x):
    message = "<ul>"
    for name, status in x.iteritems():
        message += "<li>{}: <b>{}</b></li>".format(name, status)
    message += "</ul>"
    return message

In [ ]:
# Bring up the logger
start_logging()

Create the core, menus and pipeline tree

The core object carrys all the system information and is operated on by the other classes


In [ ]:
new_core = Core()
data_menu = DataMenu()
project_menu = ProjectMenu()
module_menu = ModuleMenu()
pipe_tree = Tree()

Create a new project


In [ ]:
project_title = "DTOcean"  
new_project = project_menu.new_project(new_core, project_title)

Connect a database


In [ ]:
credentials = {"host": "localhost",
               "dbname": "dtocean_examples",
               "user": "dtocean_user",
               "pwd": "Lipicana19"} # Fill in password

data_menu.select_database(new_project, credentials=credentials)

Set the device type


In [ ]:
options_branch = pipe_tree.get_branch(new_core, new_project, "System Type Selection")
variable_id = "device.system_type"
my_var = options_branch.get_input_variable(new_core, new_project, variable_id)
my_var.set_raw_interface(new_core, "Tidal Fixed")
my_var.read(new_core, new_project)

Initiate the pipeline

This step will be important when the database is incorporated into the system as it will effect the operation of the pipeline.


In [ ]:
project_menu.initiate_pipeline(new_core, new_project)

Retrieve the available site and technology options from the DB


In [ ]:
project_menu.initiate_options(new_core, new_project)

In [ ]:
options_branch = pipe_tree.get_branch(new_core, new_project, 'Site and System Options')
options_branch.read_auto(new_core, new_project)
input_status = options_branch.get_input_status(new_core, new_project)
message = html_dict(input_status)
HTML(message)

Check available device names


In [ ]:
my_var = options_branch.get_output_variable(new_core, new_project, "device.available_names")
site_list = my_var.get_value(new_core, new_project)
msg = html_list(site_list)
HTML(msg)

Select a device


In [ ]:
filter_branch = pipe_tree.get_branch(new_core, new_project, 'Database Filtering Interface')
new_var = filter_branch.get_input_variable(new_core, new_project,
                                            "device.selected_name")
new_var.set_raw_interface(new_core, "Example Tidal Device")
new_var.read(new_core, new_project)

In [ ]:
input_status = filter_branch.get_input_status(new_core, new_project)
message = html_dict(input_status)
HTML(message)

Check the available site names


In [ ]:
available_locations = options_branch.get_output_variable(new_core, new_project,
                                                         "site.available_names")
message = html_list(available_locations.get_value(new_core, new_project))
message = "<h3>Available Locations</h3>" + message
HTML(message)

Add the site location


In [ ]:
new_var = filter_branch.get_input_variable(new_core, new_project,
                                           "site.selected_name")
new_var.set_raw_interface(new_core, "Example Tidal Site")
new_var.read(new_core, new_project)

In [ ]:
input_status = filter_branch.get_input_status(new_core, new_project)
message = html_dict(input_status)
HTML(message)

Collect the bathymetric data

The lease area polygon may be editied following this step.


In [ ]:
project_menu.initiate_bathymetry(new_core, new_project)

Filter the database


In [ ]:
project_menu.initiate_filter(new_core, new_project)

Discover available modules


In [ ]:
names = module_menu.get_available(new_core, new_project)
message = html_list(names)
HTML(message)

Activate a module

Note that the order of activation is important and that we can't deactivate yet!


In [ ]:
module_name = 'Hydrodynamics'
module_menu.activate(new_core, new_project, module_name)
hydro_branch = pipe_tree.get_branch(new_core, new_project, 'Hydrodynamics')

Check the status of the module inputs


In [ ]:
input_status = hydro_branch.get_input_status(new_core, new_project)
message = html_dict(input_status)
HTML(message)

Initiate the dataflow

This indicates that the filtering and module / theme selections are complete


In [ ]:
project_menu.initiate_dataflow(new_core, new_project)

Move the system to the post-filter state and ready the system


In [ ]:
new_core.inspect_level(new_project, "modules initial")
new_core.reset_level(new_project, preserve_level=True)

Get data using DTOcean DB

Using the auto_connect method on a branch, we can pull available variables from the database


In [ ]:
hydro_branch.read_auto(new_core, new_project)
input_status = hydro_branch.get_input_status(new_core, new_project)
message = html_dict(input_status)
HTML(message)

Auto plot a variable


In [ ]:
new_var = hydro_branch.get_input_variable(new_core,
                                          new_project,
                                          'device.turbine_performance')

In [ ]:
new_var.plot(new_core, new_project)

Look for other available plots


In [ ]:
plots = new_var.get_available_plots(new_core, new_project)
msg = html_list(plots)
HTML(msg)

Plot a specific plot


In [ ]:
new_var.plot(new_core, new_project, 'Tidal Power Performance')

Check if the module can be executed


In [ ]:
can_execute = module_menu.is_executable(new_core, new_project, module_name)
display(can_execute)

In [ ]:
input_status = hydro_branch.get_input_status(new_core, new_project)
message = html_dict(input_status)
HTML(message)

Enter user options and project data


In [ ]:
power_bin_width = hydro_branch.get_input_variable(new_core, new_project, "options.power_bin_width")
power_bin_width.set_raw_interface(new_core, 0.04)
power_bin_width.read(new_core, new_project)

rated_power = hydro_branch.get_input_variable(new_core, new_project, "project.rated_power")
rated_power.set_raw_interface(new_core, 10.)
rated_power.read(new_core, new_project)

tidal_occurrence_nbins = hydro_branch.get_input_variable(new_core, new_project, "project.tidal_occurrence_nbins")
tidal_occurrence_nbins.set_raw_interface(new_core, 12)
tidal_occurrence_nbins.read(new_core, new_project)

user_array_option = hydro_branch.get_input_variable(new_core, new_project, "options.user_array_option")
user_array_option.set_raw_interface(new_core, "Rectangular")
user_array_option.read(new_core, new_project)

optimisation_threshold = hydro_branch.get_input_variable(new_core, new_project, "options.optimisation_threshold")
optimisation_threshold.set_raw_interface(new_core, 0.9)
optimisation_threshold.read(new_core, new_project)

Execute the current module

The "current" module refers to the next module to be executed in the chain (pipeline) of modules. This command will only execute that module and another will be used for executing all of the modules at once.

Note, any data supplied by the module will be automatically copied into the active data state.


In [ ]:
module_menu.execute_current(new_core, new_project)

Examine the results

Currently, there is no robustness built into the core, so the assumption is that the module executed successfully. This will have to be improved towards deployment of the final software.

Let's check the number of devices and annual output of the farm, using just information in the data object.


In [ ]:
n_devices = new_core.get_data_value(new_project, "project.number_of_devices")
meta = new_core.get_metadata("project.number_of_devices")
name = meta.title
message_one = "<p><b>{}:</b> {}</p>".format(name, n_devices)

farm_annual_energy = new_core.get_data_value(new_project, "project.annual_energy")
meta = new_core.get_metadata("project.annual_energy")
name = meta.title
value = farm_annual_energy
units = meta.units[0]
message_two = "<p><b>{}:</b> <i>{}</i> ({})</p>".format(name, value, units)

HTML(message_one + message_two)

Plotting some graphs

By having data objects with set formats it should be possible to create automated plot generation. However, some plots may be too complex and some special cases may need defined.


In [ ]:
mean_power_per_dev_value = new_core.get_data_value(new_project, 
                                                   "project.mean_power_per_device")
meta = new_core.get_metadata("project.mean_power_per_device")

chart_values = np.array(mean_power_per_dev_value.values())

In [ ]:
plt.bar(range(len(mean_power_per_dev_value)),
        chart_values,
        align='center')
            
plt.xticks(range(len(mean_power_per_dev_value)),
          mean_power_per_dev_value.keys())
plt.title(meta.title)

plt.ylabel(meta.units[0])

plt.tight_layout()
# plt.savefig('annual_power_per_device.png')
plt.show()

Plotting the Layout

This may require such a special case. It is not clear is a new data type is required or just special plots associated to variable IDs.


In [ ]:
layout_value = new_core.get_data_value(new_project, "project.layout")
layout_meta = new_core.get_metadata("project.layout")

In [ ]:
x = []
y = []

for coords in layout_value.itervalues():
    
    x.append(coords.x)
    y.append(coords.y)

fig = plt.figure()
ax1 = fig.add_subplot(1,1,1, axisbg='lightskyblue')
ax1.plot(x,y,'k+', mew=2, markersize=10)
plt.title(layout_meta.title)
plt.axis('equal')
plt.show()

In [ ]: