# This file is part of Sympathy for Data.
# Copyright (c) 2013, 2017, Combine Control Systems AB
#
# SYMPATHY FOR DATA COMMERCIAL LICENSE
# You should have received a link to the License with Sympathy for Data.
from sympathy.api import qt2 as qt_compat
from sympathy.api import node as synode
from sympathy.api.nodeconfig import Port, Ports, Tag, Tags
from sympathy.api.exceptions import SyDataError
from sympathy.api.exceptions import SyConfigurationError
from sympathy.api.exceptions import sywarn
QtGui = qt_compat.import_module('QtGui')
QtWidgets = qt_compat.import_module('QtWidgets')
COMMON_DOCS = """
When converting a raster, its timebasis will be given the name of the raster.
Note that if the name of the raster also exists among the names of the
timeseries in that raster, the timebasis for that raster will not be included
in the output Table.
See also :ref:`working_with_adafs` for tips about how to use these conversion
nodes.
"""
RELATED = [
'org.sysess.sympathy.data.adaf.adaf2table',
'org.sysess.sympathy.data.adaf.adaf2tables',
'org.sysess.sympathy.data.adaf.adafs2tables',
'org.sysess.sympathy.data.table.table2adaf',
'org.sysess.sympathy.data.table.updateadafwithtable',
]
def write_adaf_to_table(export_group, adaffile, tablefile, tb_name=None,
tb_col_name=''):
"""Write the selected export group to a table."""
if export_group == 'Meta':
tablefile.update(adaffile.meta.to_table())
elif export_group == 'Result':
tablefile.update(adaffile.res.to_table())
elif export_group == 'Time series':
system_name, raster_name = get_system_raster_names(tb_name)
if system_name in adaffile.sys:
system = adaffile.sys[system_name]
if raster_name in system:
raster = system[raster_name]
else:
raise SyDataError(
'The selected raster does not exist in incoming ADAF')
else:
raise SyDataError(
'The selected system does not exist in incoming ADAF')
if not tb_col_name:
tb_col_name = raster_name
# Check if tb_col_name already exists in Table
if tb_col_name in raster.keys():
message = ('A column with the entered time basis column name '
'do already exist. The column will be overwritten '
'to time basis in the outgoing Table.')
sywarn(message)
tablefile.update(raster.to_table(tb_col_name))
source = adaffile.source_id()
if source:
tablefile.set_name(source)
def get_system_raster_names(tb_path):
"""Split time basis path, system_name/raster_name/ and the return the
system_name and the raster_name.
"""
return tuple(tb_path.split('/')[:2])
def get_raster_name(tb_path):
"""Return the raster name from given time basis path."""
system_name, raster_name = get_system_raster_names(tb_path)
return raster_name
def get_rasters_from_adaf(adafdata):
"""Return a list with the paths to all rasters in an adaf,
system_name/raster_name/
"""
if not adafdata:
return []
return ['{0}/{1}/'.format(system, raster)
for system, rastergroup in adafdata.sys.items()
for raster in rastergroup.keys()]
class ADAF2TableSuperNode(synode.Node):
author = "Alexander Busck"
icon = 'adaf2table.svg'
tags = Tags(Tag.DataProcessing.Convert)
def _get_single_tb_editor():
return synode.editors.combo_editor('', filter=True, edit=False)
def base_parameters(multiselect):
parameters = simple_base_parameters()
if multiselect:
tb_editor = synode.editors.multilist_editor(mode=False)
else:
tb_editor = _get_single_tb_editor()
parameters.set_list('tb',
label="Time basis raster",
description=(
'Specify the raster among the time resolved data '
'which will be exported'),
value=[],
editor=tb_editor)
parameters.set_string('tb_col_name',
label='Time basis column name',
description=('Specify the name for the time basis '
'column in the outgoing Table. The '
'default name is the name of the '
'selected raster.'),
value='')
return parameters
def simple_base_parameters():
parameters = synode.parameters()
parameters.set_list(
'export_group', ['Meta', 'Result', 'Time series'],
label='Export group',
description='Specify group in the ADAF which will be exported',
value=[0],
editor=synode.editors.combo_editor())
return parameters
def base_controllers():
controllers = (
synode.controller(
when=synode.field('export_group', 'value', value=['Time series']),
action=(synode.field('tb', 'enabled'),
synode.field('tb_col_name', 'enabled'))),)
return controllers
def get_params(node_context):
group_name = node_context.parameters['export_group'].selected
try:
tb_names = node_context.parameters['tb'].value_names
except Exception:
tb_names = []
try:
tb_col_name = node_context.parameters['tb_col_name'].value
except Exception:
tb_col_name = ''
return group_name, tb_names, tb_col_name
[docs]
class ADAF2Table(ADAF2TableSuperNode):
"""
The selected part can either be the one raster from the timeseries
container or the full content of either the metadata or the results
containers.
"""
name = 'ADAF to Table'
description = 'Convert selected part of an ADAF into a Table.'
nodeid = 'org.sysess.sympathy.data.adaf.adaf2table'
related = RELATED
inputs = Ports([Port.ADAF('Input ADAF', name='port1')])
outputs = Ports([Port.Table(
'Table with the content of a specified group in the incoming ADAF',
name='port1')])
parameters = base_parameters(False)
controllers = base_controllers()
def adjust_parameters(self, node_context):
if node_context.input['port1'].is_valid():
adafdata = node_context.input['port1']
else:
adafdata = None
rasters = get_rasters_from_adaf(adafdata)
node_context.parameters['tb'].adjust(rasters)
def update_parameters(self, old_params):
param = 'tb'
if param in old_params:
old_params[param].editor = _get_single_tb_editor()
def execute(self, node_context):
adaffile = node_context.input['port1']
tablefile = node_context.output['port1']
group_name, tb_names, tb_col_name = get_params(node_context)
if group_name in ('Meta', 'Result'):
write_adaf_to_table(group_name, adaffile, tablefile)
for tb_name in tb_names:
try:
write_adaf_to_table(
group_name, adaffile, tablefile, tb_name, tb_col_name)
except AttributeError as exc:
raise SyConfigurationError("Configuration error") from exc
[docs]
class ADAFs2Tables(ADAF2TableSuperNode):
"""
The selected part can either be the one raster from the timeseries
container or the full content of either the metadata or the results
containers.
"""
name = 'ADAFs to Tables'
description = 'Convert selected part of each input ADAF into a Table.'
nodeid = 'org.sysess.sympathy.data.adaf.adafs2tables'
related = RELATED
inputs = Ports([Port.ADAFs('Input ADAF', name='port1')])
outputs = Ports([Port.Tables(
'Tables with the content of a specified group in the incoming ADAFs',
name='port1')])
parameters = base_parameters(True)
controllers = base_controllers()
def adjust_parameters(self, node_context):
port1 = node_context.input['port1']
if port1.is_valid() and len(port1):
adafdata = port1[0]
else:
adafdata = None
rasters = get_rasters_from_adaf(adafdata)
node_context.parameters['tb'].adjust(rasters)
def update_parameters(self, old_params):
try:
old_params['tb'].editor['mode'] = True
except KeyError:
pass
def execute(self, node_context):
input_list = node_context.input['port1']
output_list = node_context.output['port1']
group_name, tb_names, tb_col_name = get_params(node_context)
for i, adaffile in enumerate(input_list):
if group_name in ('Meta', 'Result'):
tablefile = output_list.create()
write_adaf_to_table(group_name, adaffile, tablefile)
output_list.append(tablefile)
else:
tb_names = get_rasters_from_adaf(adaffile)
for tb_name in node_context.parameters['tb'].selected_names(
tb_names):
tablefile = output_list.create()
try:
write_adaf_to_table(
group_name, adaffile, tablefile, tb_name,
tb_col_name)
except AttributeError as exc:
raise SyConfigurationError(
"Configuration error"
) from exc
output_list.append(tablefile)
self.set_progress(100.0 * i / len(input_list))
[docs]
class ADAF2Tables(ADAF2TableSuperNode):
"""
Export of specified data from ADAF to Tables. The data can
be the full content of either the metadata, the results or the timeseries
containers.
"""
name = 'ADAF to Tables'
description = 'Export of data from an ADAF to a list of Tables.'
nodeid = 'org.sysess.sympathy.data.adaf.adaf2tables'
icon = 'adaf2tables.svg'
related = RELATED
inputs = Ports([Port.ADAF('Input ADAF', name='port1')])
outputs = Ports([Port.Tables(
'All data from an ADAF group as a Tables list', name='port1')])
parameters = simple_base_parameters()
def execute(self, node_context):
group_name = node_context.parameters['export_group'].selected
adaffile = node_context.input['port1']
output_list = node_context.output['port1']
if group_name == 'Time series':
tb_names = get_rasters_from_adaf(adaffile)
else:
tb_names = [None]
for tb_name in tb_names:
tablefile = output_list.create()
write_adaf_to_table(
group_name, adaffile, tablefile, tb_name)
output_list.append(tablefile)