<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 DTOcean Tidal Hydrodynamics + Database Example
Note, this example assumes the DTOcean database and the Hydroynamics Module has been installed
Step1:  Create the core, menus and pipeline tree
The core object carrys all the system information and is operated on by the other classes
Step2:  Create a new project
Step3:  Connect a database
Step4:  Set the device type
Step5:  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.
Step6:  Retrieve the available site and technology options from the DB
Step7:  Check available device names
Step8:  Select a device
Step9:  Check the available site names
Step10:  Add the site location
Step11:  Collect the bathymetric data
The lease area polygon may be editied following this step.
Step12:  Filter the database
Step13:  Discover available modules
Step14:  Activate a module
Note that the order of activation is important and that we can't deactivate yet!
Step15:  Check the status of the module inputs
Step16:  Initiate the dataflow
This indicates that the filtering and module / theme selections are complete
Step17:  Move the system to the post-filter state and ready the system
Step18:  Get data using DTOcean DB
Using the auto_connect method on a branch, we can pull available variables from the database
Step19:  Auto plot a variable
Step20:  Look for other available plots
Step21:  Plot a specific plot
Step22:  Check if the module can be executed
Step23:  Enter user options and project data
Step24:  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.
Step25:  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.
Step26:  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.
Step27:  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.
<ASSISTANT_TASK:>
Python Code:
%matplotlib inline
from IPython.display import display, HTML
import matplotlib.pyplot as plt
plt.rcParams['figure.figsize'] = (14.0, 8.0)
import numpy as np
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
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
# Bring up the logger
start_logging()
Explanation: DTOcean Tidal Hydrodynamics + Database Example
Note, this example assumes the DTOcean database and the Hydroynamics Module has been installed
End of explanation
new_core = Core()
data_menu = DataMenu()
project_menu = ProjectMenu()
module_menu = ModuleMenu()
pipe_tree = Tree()
Explanation: Create the core, menus and pipeline tree
The core object carrys all the system information and is operated on by the other classes
End of explanation
project_title = "DTOcean"  
new_project = project_menu.new_project(new_core, project_title)
Explanation: Create a new project
End of explanation
credentials = {"host": "localhost",
               "dbname": "dtocean_examples",
               "user": "dtocean_user",
               "pwd": "Lipicana19"} # Fill in password
data_menu.select_database(new_project, credentials=credentials)
Explanation: Connect a database
End of explanation
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)
Explanation: Set the device type
End of explanation
project_menu.initiate_pipeline(new_core, new_project)
Explanation: 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.
End of explanation
project_menu.initiate_options(new_core, new_project)
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)
Explanation: Retrieve the available site and technology options from the DB
End of explanation
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)
Explanation: Check available device names
End of explanation
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)
input_status = filter_branch.get_input_status(new_core, new_project)
message = html_dict(input_status)
HTML(message)
Explanation: Select a device
End of explanation
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)
Explanation: Check the available site names
End of explanation
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)
input_status = filter_branch.get_input_status(new_core, new_project)
message = html_dict(input_status)
HTML(message)
Explanation: Add the site location
End of explanation
project_menu.initiate_bathymetry(new_core, new_project)
Explanation: Collect the bathymetric data
The lease area polygon may be editied following this step.
End of explanation
project_menu.initiate_filter(new_core, new_project)
Explanation: Filter the database
End of explanation
names = module_menu.get_available(new_core, new_project)
message = html_list(names)
HTML(message)
Explanation: Discover available modules
End of explanation
module_name = 'Hydrodynamics'
module_menu.activate(new_core, new_project, module_name)
hydro_branch = pipe_tree.get_branch(new_core, new_project, 'Hydrodynamics')
Explanation: Activate a module
Note that the order of activation is important and that we can't deactivate yet!
End of explanation
input_status = hydro_branch.get_input_status(new_core, new_project)
message = html_dict(input_status)
HTML(message)
Explanation: Check the status of the module inputs
End of explanation
project_menu.initiate_dataflow(new_core, new_project)
Explanation: Initiate the dataflow
This indicates that the filtering and module / theme selections are complete
End of explanation
new_core.inspect_level(new_project, "modules initial")
new_core.reset_level(new_project, preserve_level=True)
Explanation: Move the system to the post-filter state and ready the system
End of explanation
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)
Explanation: Get data using DTOcean DB
Using the auto_connect method on a branch, we can pull available variables from the database
End of explanation
new_var = hydro_branch.get_input_variable(new_core,
                                          new_project,
                                          'device.turbine_performance')
new_var.plot(new_core, new_project)
Explanation: Auto plot a variable
End of explanation
plots = new_var.get_available_plots(new_core, new_project)
msg = html_list(plots)
HTML(msg)
Explanation: Look for other available plots
End of explanation
new_var.plot(new_core, new_project, 'Tidal Power Performance')
Explanation: Plot a specific plot
End of explanation
can_execute = module_menu.is_executable(new_core, new_project, module_name)
display(can_execute)
input_status = hydro_branch.get_input_status(new_core, new_project)
message = html_dict(input_status)
HTML(message)
Explanation: Check if the module can be executed
End of explanation
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)
Explanation: Enter user options and project data
End of explanation
module_menu.execute_current(new_core, new_project)
Explanation: 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.
End of explanation
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)
Explanation: 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.
End of explanation
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())
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()
Explanation: 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.
End of explanation
layout_value = new_core.get_data_value(new_project, "project.layout")
layout_meta = new_core.get_metadata("project.layout")
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()
Explanation: 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.
End of explanation
<END_TASK>