Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
__all__ = ['GroupedInnotation', 'RepeatInnotation']
from ipywidgets import HBox, VBox, Button
from .data import Innotation
from .mixins import ChildrenChangeNotifierMixin
class GroupedInnotation(Innotation):
def __init__(self, *args, **kwargs):
super().__init__(**kwargs)
self.childinnotations = args
def post_register(self, datamanager):
for innot in self.childinnotations:
innot.post_register(datamanager)
def post_widget_create(self, datamanager):
for innot in self.childinnotations:
innot.post_widget_create(datamanager)
def _create_widget(self):
__all__ = ['ButtonInnotation']
from ipywidgets import Button
from .data import Innotation
from .mixins import DataChangeNotifierMixin
class ButtonInnotation(Innotation, DataChangeNotifierMixin):
"""
Allow embedding of an arbitrary widget object, e.g. for text display
Must still have a data attribute of correct len, even if dummy values
"""
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.on_click_hook = kwargs.get('on_click', None)
self.uindex = None
def _create_widget(self):
btn = Button(description=self.desc, disabled=self.disabled, layout=self.layout)
if self.on_click_hook:
btn.on_click(lambda b: self.call_on_click_hook(b))
return btn
self.get_widget().observe(fn, names=names)
def update_ui(self, uindex):
raise Exception('Do not call update_ui on base class, Innotation {} with name {}'.format(type(self), self.name))
def update_data(self, uindex):
raise Exception('Do not call update_data on an input-only class, Innotation {} with name {}'.format(type(self), self.name))
def contains_widget(self, widget):
return self.get_widget() == widget
def list_innotations_tree(self):
return [self]
class ImageInnotation(Innotation, DataMixin):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.width = kwargs.get('width', 0)
self.height = kwargs.get('height', 0)
self.path = kwargs.get('path', '')
self.transform = kwargs.get('transform', None)
self.annotation_styles = kwargs.get('annotation_styles', {})
self.colorspace = 'BGR'
if 'colorspace' in kwargs:
self.colorspace = kwargs['colorspace']
def __init__(self, inputs, targets, indexes=None):
if inputs is None: inputs = []
if targets is None: targets = []
self.inputs = [inputs] if isinstance(inputs, Innotation) else inputs
self.targets = [targets] if isinstance(targets, Innotation) else targets
self.alldws = {}
l = -1
for dw in self.inputs+self.targets:
l = self._add_to_alldws(dw, l)
self.underlying_len = l
self.indexes = indexes
if indexes is not None:
if len(indexes) == 0:
raise Exception("indexes must be a non-empty array-like containing integers or booleans")
# boolean or numpy.bool_ - and might be a col vector
self.max_repeats += 1
self.get_widget().set_max_repeats(self.max_repeats)
self.watchlist.add(Watcher(name=name, repeat_index=repeat_index))
def get_current_watcher(self):
return self.watchlist[self.get_widget().rect_index]
def set_current_watcher(self, name, repeat_index):
self.get_widget().rect_index = self.watchlist.get_watcher_index(name, repeat_index)
def get_rect_for_watcher(self, name, repeat_index):
watcher_index = self.watchlist.get_watcher_index(name, repeat_index)
return self.get_widget().rects[watcher_index*4:(watcher_index+1)*4]
class BoundingBoxInnotation(Innotation, DataMixin):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.source = kwargs.get('source', None)
self.sourcedw = None
def post_register(self, datamanager):
if self.source is not None:
self.sourcedw = datamanager.get_data_wrapper_by_name(self.source)
if self.sourcedw is None:
raise Exception('ImageInnotation named {} not found but specified as source attribute for BoundingBoxInnotation'.format(self.source))
if not isinstance(self.sourcedw, ImageInnotation):
def rectIndexChanged(self, change):
if self.sourcedw is not None:
#if self.sourcedw.get_widget().rect_index == self.repeat_index:
watcher = self.sourcedw.get_current_watcher()
if watcher.name == self.name and watcher.repeat_index == self.repeat_index:
self.get_widget().add_class('bounding-box-active')
else:
self.get_widget().remove_class('bounding-box-active')
def widget_clicked(self, w):
if self.sourcedw is not None:
self.sourcedw.set_current_watcher(self.name, self.repeat_index)
class MultiClassInnotation(Innotation, DataMixin):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# Just a 1-dim array with values corresponding to class numbers e.g. 0-5
self.datadepth = 'simple'
self.dims = 1
if hasattr(self._get_data(0), '__len__'):
self.dims = 2
if self.dims > 1:
if len(self._get_data(0)) == 1:
self.datadepth = 'colvector' # A column vector corresponding to class numbers directly
else:
class BinaryClassInnotation(MultiClassInnotation):
def _guess_classes(self):
self.classes = ['False', 'True']
def _create_widget(self):
return Checkbox(description=self.desc, layout=self.layout, disabled=self.disabled)
def update_ui(self, uindex):
self.get_widget().value = bool(self._calc_class_index(uindex) == 1)
def _get_widget_value(self):
return self.classes[self.get_widget().value and 1 or 0]
class TextInnotation(Innotation, DataMixin):
def __init__(self, *args, **kwargs):
self.multiline = kwargs.get('multiline', True)
super().__init__(*args, **kwargs)
def _create_widget(self):
if self.multiline:
return Textarea(layout=self.layout, disabled=self.disabled)
return Text(layout=self.layout, disabled=self.disabled)
def update_ui(self, uindex):
self.get_widget().value = str(self._get_data(uindex))
def update_data(self, uindex):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
if 'name' in kwargs:
self.name = kwargs['name']
else:
self.name = 'data{}'.format(Innotation.anonindex)
Innotation.anonindex += 1
self.desc = kwargs.get('desc', self.name)
self.widget = None
self.layout = kwargs.get('layout', {})
if 'disabled' in kwargs:
self.disabled = kwargs['disabled']
def __init__(self, inputs, targets, indexes=None):
if inputs is None: inputs = []
if targets is None: targets = []
self.inputs = [inputs] if isinstance(inputs, Innotation) else inputs
self.targets = [targets] if isinstance(targets, Innotation) else targets
self.alldws = {}
l = -1
for dw in self.inputs+self.targets:
l = self._add_to_alldws(dw, l)
self.underlying_len = l
self.indexes = indexes
if indexes is not None:
if len(indexes) == 0:
raise Exception("indexes must be a non-empty array-like containing integers or booleans")
def contains_widget(self, widget):
for innot in self.childinnotations:
if innot.contains_widget(widget):
return True
return False
def list_innotations_tree(self):
return [self, *self.childinnotations]
def __len__(self):
if len(self.childinnotations) > 0:
return len(self.childinnotations[0])
return 0
class RepeatInnotation(Innotation, ChildrenChangeNotifierMixin):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.rows_count = 0
self.childinnotationconfigs = args
self.childinnotations = []
self.min_repeats = kwargs.get('min_repeats', 0)
self.max_repeats = kwargs.get('max_repeats', 10)
if self.max_repeats < self.min_repeats:
raise Exception("min_repeats is greater than max_repeats")