Skip to content

Commit

Permalink
refact(table): encapsulate buf.getCell() & improve logging
Browse files Browse the repository at this point in the history
+ Centralize error-reporting for cell indexing-errors.
+ Logging:
  + Restore start offset-logging on cell indexing errors.
  + Class-logger-->module-var, not to waste loggers with each new
object.
  + Stop specifying log-levels (must be done to all loggers).
  • Loading branch information
ankostis committed Jun 14, 2017
1 parent 3df3d48 commit a105834
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 45 deletions.
14 changes: 8 additions & 6 deletions vitables/plugins/timeseries/time_series.py
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ def customiseModel(self, datasheet):
leaf_kind = 'array'
model_info = {
'leaf_kind': leaf_kind,
'rbuffer': model.rbuffer,
'model': model,
'numrows': model.rowCount(),
'formatContent': model.formatContent,
}
Expand Down Expand Up @@ -298,7 +298,7 @@ def __init__(self, model_info, ts_info, parent=None):
self.ts_freq = ts_info['ts_freq']
self.ts_format = ts_info['ts_format']
# Attributes required by the data() method
self.rbuffer = model_info['rbuffer']
self.model = model_info['model']
self.numrows = model_info['numrows']
self.ts_cols = ts_info['ts_cols']
self.formatContent = model_info['formatContent']
Expand All @@ -322,12 +322,13 @@ def table_data(self, index, role=QtCore.Qt.DisplayRole):
- `index`: the index of a data item
- `role`: the role being returned
"""
row, col = index.row(), index.column()

if not index.isValid() or not (0 <= index.row() < self.nrows):
if not index.isValid() or not (0 <= row < self.nrows):
return None

if role == QtCore.Qt.DisplayRole:
cell = self.rbuffer.getCell(index.row(), index.column())
cell = self.model.cell(row, col)
if index.column() in self.ts_cols:
return self.tsFormatter(cell)
return self.formatContent(cell)
Expand All @@ -348,12 +349,13 @@ def array_data(self, index, role=QtCore.Qt.DisplayRole):
- `index`: the index of a data item
- `role`: the role being returned
"""
row, col = index.row(), index.column()

if not index.isValid() or not (0 <= index.row() < self.nrows):
if not index.isValid() or not (0 <= row < self.nrows):
return None

if role == QtCore.Qt.DisplayRole:
cell = self.rbuffer.getCell(index.row(), index.column())
cell = self.model.cell(row, col)
return self.tsFormatter(cell)

if role == QtCore.Qt.TextAlignmentRole:
Expand Down
36 changes: 9 additions & 27 deletions vitables/vttables/buffer.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@
warnings.filterwarnings('ignore', category=tables.FlavorWarning)
warnings.filterwarnings('ignore', category=tables.NaturalNameWarning)

log = logging.getLogger(__name__)


class Buffer(object):
"""Buffer used to access the real data contained in `PyTables` datasets.
Expand Down Expand Up @@ -81,9 +83,6 @@ def __init__(self, leaf):
Initializes the buffer.
"""

self.logger = logging.getLogger(__name__)
self.logger.setLevel(logging.INFO)

self.leaf = leaf

# The numpy array where read data will be stored
Expand Down Expand Up @@ -161,7 +160,7 @@ def isDataSourceReadable(self):
except tables.HDF5ExtError:
readable = False
# TODO: Fix error msg to include exception or merge with below.
self.logger.error(
log.error(
translate('Buffer',
"""Problems reading records. The dataset """
"""seems to be compressed with the {0} library. """
Expand All @@ -171,7 +170,7 @@ def isDataSourceReadable(self):
self.leaf.filters.complib))
except ValueError as e:
readable = False
self.logger.error(
log.error(
translate('Buffer', 'Data read error: {}',
'A dataset read error').format(e.message))
return readable
Expand Down Expand Up @@ -204,7 +203,7 @@ def readBuffer(self, start, stop):
data = self.leaf.read(start, stop)
except tables.HDF5ExtError:
# TODO: Fix error msg to include exception.
self.logger.error(
log.error(
translate('Buffer', """\nError: problems reading records. """
"""The dataset maybe corrupted.""",
'A dataset readability error'))
Expand All @@ -228,12 +227,7 @@ def scalarCell(self, row, col):
:Returns: the cell at position `(row, col)` of the document
"""

try:
return self.chunk[()]
except IndexError:
self.logger.error('IndexError! row, column: {1}, {2}'
.format(row, col))
return self.chunk[()]

def vectorCell(self, row, col):
"""
Expand All @@ -260,11 +254,7 @@ def vectorCell(self, row, col):
# get the right chunk element.
# chunk = [row0, row1, row2, ..., rowN]
# and columns can be read from a given row using indexing notation
try:
return self.chunk[row]
except IndexError:
self.logger.error('IndexError! row, column: {1}, {2}'
.format(row, col))
return self.chunk[row]

def EArrayCell(self, row, col):
"""
Expand All @@ -287,11 +277,7 @@ def EArrayCell(self, row, col):
# and columns can be read from a given row using indexing notation
# TODO: this method should be improved as it requires to read the
# whola array keeping the read data in memory
try:
return self.leaf.read()[row]
except IndexError:
self.logger.error('IndexError! row, column: {1}, {2}'
.format(row, col))
return self.leaf.read()[row]

def arrayCell(self, row, col):
"""
Expand All @@ -316,8 +302,4 @@ def arrayCell(self, row, col):
# For tables we have
# chunk = [nestedrecord0, nestedrecord1, ..., nestedrecordN]
# and fields can be read from nestedrecordJ using indexing notation
try:
return self.chunk[row][col]
except IndexError:
self.logger.error('IndexError! row, column: {1}, {2}'
.format(row, col))
return self.chunk[row][col]
12 changes: 4 additions & 8 deletions vitables/vttables/datasheet.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,6 @@ def __init__(self, index):
self.aboutToActivate.connect(self.syncTreeView)
self.leaf_view.doubleClicked.connect(self.zoomCell)


def closeEvent(self, event):
"""Close the window cleanly with the close button of the title bar.
Expand All @@ -112,7 +111,6 @@ def closeEvent(self, event):
if self.vtgui.workspace.subWindowList() == []:
self.vtgui.dbs_tree_view.setFocus(True)


def focusInEvent(self, event):
"""Specialised handler for focus events.
Expand All @@ -128,7 +126,6 @@ def focusInEvent(self, event):
self.syncTreeView()
self.setFocus(True)


def syncTreeView(self):
"""
If the view is activated select its leaf in the tree of databases view.
Expand All @@ -143,7 +140,6 @@ def syncTreeView(self):
self.vtgui.dbs_tree_view.setCurrentIndex(
QtCore.QModelIndex(self.pindex))


def zoomCell(self, index):
"""Display the inner dimensions of a cell.
Expand All @@ -153,18 +149,18 @@ def zoomCell(self, index):
row = index.row()
column = index.column()
tmodel = index.model()
data = tmodel.rbuffer.getCell(row, column)
data = tmodel.cell(row, column)

# The title of the zoomed view
node = self.dbt_leaf
info = nodeinfo.NodeInfo(node)
if node.node_kind == 'table':
col = info.columns_names[column]
title = '{0}: {1}[{2}]'.format(node.name, col,
tmodel.start + row)
tmodel.start + row)
else:
title = '{0}: ({1},{2})'.format(node.name,
tmodel.start + row, column)
tmodel.start + row, column)

zoom_cell.ZoomCell(data, title, self.vtgui.workspace,
self.dbt_leaf)
self.dbt_leaf)
18 changes: 14 additions & 4 deletions vitables/vttables/leaf_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,19 @@

__docformat__ = 'restructuredtext'

import logging
import vitables.utils
from vitables.vttables import buffer

from qtpy import QtCore
import tables

from vitables.vttables import buffer


#: The maximum number of rows to be read from the data source.
CHUNK_SIZE = 10000

log = logging.getLogger(__name__)


class LeafModel(QtCore.QAbstractTableModel):
"""
Expand Down Expand Up @@ -207,15 +209,23 @@ def data(self, index, role=QtCore.Qt.DisplayRole):
- `index`: the index of a data item
- `role`: the role being returned
"""
row, col = index.row(), index.column()

if not index.isValid() or not (0 <= index.row() < self.numrows):
if not index.isValid() or not (0 <= row < self.numrows):
return None

if role == QtCore.Qt.DisplayRole:
cell = self.rbuffer.getCell(index.row(), index.column())
cell = self.cell(row, col)
return self.formatContent(cell)

if role == QtCore.Qt.TextAlignmentRole:
return QtCore.Qt.AlignLeft | QtCore.Qt.AlignTop

return None

def cell(self, row, col):
try:
return self.rbuffer.getCell(row, col)
except IndexError:
log.error('IndexError! buffer start: {0} row, column: '
'{1}, {2}'.format(self.start, row, col))

0 comments on commit a105834

Please sign in to comment.