Source code for ladybug.header
# coding=utf-8
"""Ladybug Header"""
from __future__ import division
from copy import deepcopy
from .analysisperiod import AnalysisPeriod
from .datatype.base import DataTypeBase
[docs]class Header(object):
"""DataCollection header.
Header carries meatdata for DataCollections including data type, unit
and analysis period.
Args:
data_type: A DataType object. (e.g. Temperature)
unit: data_type unit (e.g. 'C').
analysis_period: A Ladybug AnalysisPeriod object.
metadata: Optional dictionary of additional metadata,
containing information such as 'source', 'city', or 'zone'.
Properties:
* data_type
* unit
* analysis_period
* metadata
"""
__slots__ = ('_data_type', '_unit', '_analysis_period', '_metadata')
def __init__(self, data_type, unit, analysis_period, metadata=None):
"""Initiate Ladybug header for lists.
"""
assert isinstance(data_type, DataTypeBase), \
'data_type must be a Ladybug DataType. Got {}'.format(type(data_type))
data_type.is_unit_acceptable(unit)
assert isinstance(analysis_period, AnalysisPeriod), \
'analysis_period must be a Ladybug AnalysisPeriod. Got {}'.format(
type(analysis_period))
if metadata is not None:
assert isinstance(metadata, dict), \
'metadata must be a dictionary. Got {}'.format(type(metadata))
self._data_type = data_type
self._unit = unit
self._analysis_period = analysis_period
self.metadata = metadata
[docs] @classmethod
def from_dict(cls, data):
"""Create a header from a dictionary.
Args:
data: A python dictionary in the following format
.. code-block:: python
{
"data_type": {}, # Type of data (e.g. Temperature)
"unit": "", # string
"analysis_period": {}, # A Ladybug AnalysisPeriod
"metadata": {} # A dictionary of metadata
}
"""
# assign default values
assert 'data_type' in data, 'Required Header key "data_type" is missing!'
assert 'unit' in data, 'Required Header key "unit" is missing!'
assert 'analysis_period' in data, \
'Required Header key "analysis_period" is missing!'
data_type = DataTypeBase.from_dict(data['data_type'])
ap = AnalysisPeriod.from_dict(data['analysis_period'])
metadata = data['metadata'] if 'metadata' in data else None
return cls(data_type, data['unit'], ap, metadata)
[docs] @classmethod
def from_csv_strings(cls, csv_strings, analysis_period):
"""Load a header from a list of CSV strings.
Args:
csv_strings: A list of CSV strings representing the header.
analysis_period: An AnalysisPeriod object for the header.
"""
data_type = DataTypeBase.from_string(csv_strings[0])
if len(csv_strings) > 2:
all_props = [p for prop in csv_strings[2:] for p in prop.split(' | ')]
metadata = {}
for p in all_props:
p_split = p.split(': ')
metadata[p_split[0]] = p_split[1]
else:
metadata = None
return cls(data_type, csv_strings[1], analysis_period, metadata)
@property
def data_type(self):
"""Get a DataType object."""
return self._data_type
@property
def unit(self):
"""Get a text string representing an abbreviated unit (eg. 'C')."""
return self._unit
@property
def analysis_period(self):
"""Get an AnalysisPeriod object."""
return self._analysis_period
@property
def metadata(self):
"""Get or set a dictionary of metadata associated with the Header."""
return self._metadata
@metadata.setter
def metadata(self, value):
if value is not None:
assert isinstance(value, dict), \
'Expected dictionary for Header metadata. Got {}.'.format(type(value))
self._metadata = value or {}
def __copy__(self):
a_per = self.analysis_period.duplicate() if self.analysis_period else None
return self.__class__(self.data_type, self.unit, a_per, deepcopy(self.metadata))
[docs] def to_tuple(self):
"""Return Ladybug header as a list."""
return (
self.data_type,
self.unit,
self.analysis_period,
self.metadata
)
def __iter__(self):
"""Return data as tuple."""
return iter(self.to_tuple())
[docs] def to_dict(self):
"""Return a header as a dictionary."""
a_per = self.analysis_period.to_dict() if self.analysis_period else None
return {
'data_type': self.data_type.to_dict(),
'unit': self.unit,
'analysis_period': a_per,
'metadata': self.metadata,
'type': 'Header',
}
[docs] def to_csv_strings(self, metadata_per_row=False):
"""Return the header as a list of CSV strings.
Args:
metadata_per_row: Boolean to note whether each metadata variable
should be a separate item in the resulting list or all items
should be on a single line. (Default: False).
"""
meta_str = ['{}: {}'.format(k, v) for k, v in self.metadata.items()]
if metadata_per_row:
return [self.data_type.to_string(), self.unit] + meta_str
else:
return [self.data_type.to_string(), self.unit, ' | '.join(meta_str)]
def __key(self):
return (str(self.data_type), self.unit, self.analysis_period)
def __hash__(self):
return hash(self.__key())
def __eq__(self, other):
return isinstance(other, Header) and self.__key() == other.__key() and \
self.metadata == other.metadata
def __ne__(self, value):
return not self.__eq__(value)
def __repr__(self):
"""Return Ladybug header as a string."""
a_per = self.analysis_period if self.analysis_period else ''
if self.metadata != {}:
meta_str = '\n'.join(['{}: {}'.format(key, val)
for key, val in self.metadata.items()])
return "{} ({})\n{}\n{}".format(
self.data_type, self.unit, a_per, meta_str)
else:
return "{} ({})\n{}".format(
self.data_type, self.unit, a_per)