from .Component import Component
from .Sample import Sample
[docs]class Container(Component):
"""
Entity class holding state of any hierarchical sample container
"""
def __init__(self, type, container, address, scannable):
super(Container, self).__init__(container, address, scannable)
self.type = type
self.components = []
######################### PUBLIC #########################
[docs] def get_type(self):
"""
Returns a description of the type of container
Known types:
- Puck
- Vial
- Plate
- Well
- SC3
- PlateSupport
- GRob
:rtype: str
"""
return self.type
[docs] def get_components(self):
"""
Returns the list of components of this container
:rtype: list
"""
return self.components
def get_number_of_components(self):
return len(self.components)
[docs] def get_sample_list(self):
"""
Returns the list of all Sample objects under of this container (recursively)
:rtype: list
"""
samples = []
for c in self.get_components():
if isinstance(c, Sample):
samples.append(c)
else:
samples.extend(c.get_sample_list())
return samples
def get_basket_list(self):
basket_list = []
for basket in self.components:
if isinstance(basket, Basket):
basket_list.append(basket)
return basket_list
[docs] def get_present_samples(self):
"""
Returns the list of all Sample objects under of this container (recursively) tagged as present
:rtype: list
"""
ret = []
for sample in self.get_sample_list():
if sample.is_present():
ret.append(sample)
[docs] def is_empty(self):
"""
Returns true if there is no sample present sample under this container
:rtype: bool
"""
for s in self.get_sample_list():
if s.is_present():
return False
return True
[docs] def get_component_by_address(self, address):
"""
Returns a component through its slot address or None if address is invalid
:rtype: Component
"""
for c in self.get_components():
if c.get_address() == address:
return c
if isinstance(c, Container):
aux = c.get_component_by_address(address)
if aux is not None:
return aux
return None
[docs] def has_component_address(self, address):
"""
Returns if has a component with a given address
:rtype: bool
"""
return self.get_component_by_address(address) is not None
[docs] def get_component_by_id(self, id):
"""
Returns a component through its id or None if id is invalid
:rtype: Component
"""
for c in self.get_components():
if c.get_id() == id:
return c
if isinstance(c, Container):
aux = c.get_component_by_id(id)
if aux is not None:
return aux
return None
[docs] def has_component_id(self, id):
"""
Returns if has a component with a given ID
:rtype: bool
"""
return self.get_component_by_id(id) is not None
def get_selected_sample(self):
for s in self.get_sample_list():
if s.is_selected():
return s
return None
def get_selected_component(self):
for c in self.get_components():
if c.is_selected():
return c
return None
[docs] def clear_info(self):
Component._reset_dirty(self)
for c in self.get_components():
c.clear_info()
######################### PROTECTED #########################
def _add_component(self, c):
self.components.append(c)
def _remove_component(self, c):
self.components.remove(c)
def _clear_components(self):
self.components = []
def _reset_dirty(self):
Component._reset_dirty(self)
for c in self.get_components():
c._reset_dirty()
def _set_selected_sample(self, sample):
for s in self.get_sample_list():
if s == sample:
s._set_selected(True)
else:
s._set_selected(False)
def _set_selected_component(self, component):
if component is None:
for c in self.get_components():
c._set_selected(False)
else:
component._set_selected(True)
def _set_selected(self, selected):
if not selected:
for c in self.get_components():
c._set_selected(False)
Component._set_selected(self, selected)
[docs]class Basket(Container):
__TYPE__ = "Puck"
def __init__(self, container, number, samples_num=10, name="Puck"):
super(Basket, self).__init__(
self.__TYPE__, container, Basket.get_basket_address(number), True
)
self._name = name
self.samples_num = samples_num
for i in range(samples_num):
slot = Pin(self, number, i + 1)
self._add_component(slot)
@staticmethod
def get_basket_address(basket_number):
return str(basket_number)
def get_number_of_samples(self):
return self.samples_num
[docs] def clear_info(self):
# self.get_container()._reset_basket_info(self.get_index()+1)
self.get_container()._trigger_info_changed_event()
[docs]class Pin(Sample):
STD_HOLDERLENGTH = 22.0
def __init__(self, basket, basket_no, sample_no):
super(Pin, self).__init__(
basket, Pin.get_sample_address(basket_no, sample_no), False
)
self._set_holder_length(Pin.STD_HOLDERLENGTH)
def get_basket_no(self):
return self.get_container().get_index() + 1
def get_vial_no(self):
return self.get_index() + 1
@staticmethod
def get_sample_address(basket_number, sample_number):
return "%s:%02d" % (basket_number, sample_number)