def __create_instructions_file(self): """ Creates the instruction file for the :attr:`entity` (printer :attr:`mode` only). """ rack_containers = [] for containers in self.__rack_containers.values(): rack_containers.extend(containers) for sr_label, stock_rack in self._stock_racks.iteritems(): values = LABELS.parse_rack_label(sr_label) rack_marker = values[LABELS.MARKER_RACK_MARKER] container = IsoRackContainer(rack=stock_rack.rack, rack_marker=rack_marker, label=sr_label, role=LABELS.ROLE_STOCK) rack_containers.append(container) kw = dict(entity=self.entity, iso_request=self._iso_request, rack_containers=rack_containers, parent=self) writer = create_instructions_writer(**kw) instructions_stream = writer.get_result() if instructions_stream is None: msg = 'Error when trying to generate instructions file.' self.add_error(msg) return None return instructions_stream
def __create_instructions_file(self): """ Creates the instruction file for the :attr:`entity` (printer :attr:`mode` only). """ rack_containers = [] for containers in self.__rack_containers.values(): rack_containers.extend(containers) for sr_label, stock_rack in self._stock_racks.iteritems(): values = LABELS.parse_rack_label(sr_label) rack_marker = values[LABELS.MARKER_RACK_MARKER] container = IsoRackContainer(rack=stock_rack.rack, rack_marker=rack_marker, label=sr_label, role=LABELS.ROLE_STOCK) rack_containers.append(container) kw = dict(entity=self.entity, iso_request=self._iso_request, rack_containers=rack_containers, parent=self) writer = create_instructions_writer(**kw) instructions_stream = writer.get_result() if instructions_stream is None: msg = 'Error when trying to generate instructions file.' self.add_error(msg) return None return instructions_stream
def _store_rack_container(self, rack, role, label=None, rack_marker=None): """ Helper function creating a :class:`IsoRackContainer` for a rack. The containers are store in the :attr:`_rack_containers` map. """ if label is None: label = rack.label if rack_marker is None: values = LABELS.parse_rack_label(label) rack_marker = values[LABELS.MARKER_RACK_MARKER] rack_container = IsoRackContainer(rack=rack, label=label, role=role, rack_marker=rack_marker) self._rack_containers[label] = rack_container
def _store_rack_container(self, rack, role, label=None, rack_marker=None): """ Helper function creating a :class:`IsoRackContainer` for a rack. The containers are store in the :attr:`_rack_containers` map. """ if label is None: label = rack.label if rack_marker is None: values = LABELS.parse_rack_label(label) rack_marker = values[LABELS.MARKER_RACK_MARKER] rack_container = IsoRackContainer(rack=rack, label=label, role=role, rack_marker=rack_marker) self._rack_containers[label] = rack_container
def set_iso_count(self, iso_count): """ In order to avoid duplicate transfers ISO preparation plate for job are only recorded once regardless of the number of ISOs in the job. When calculating the volumes the take out volume of the remaining positions are multiplied by the ISO count). """ self.__iso_count = iso_count for plate_label in sorted(self.__prep_positions.keys()): try: value_parts = LABELS.parse_rack_label(plate_label) except ValueError: # the label is an ISO preparation plate marker role = LABELS.ROLE_PREPARATION_ISO else: role = value_parts[LABELS.MARKER_RACK_ROLE] if role == LABELS.ROLE_PREPARATION_JOB: self.__job_plate_labels.add(plate_label)
def set_iso_count(self, iso_count): """ In order to avoid duplicate transfers ISO preparation plate for job are only recorded once regardless of the number of ISOs in the job. When calculating the volumes the take out volume of the remaining positions are multiplied by the ISO count). """ self.__iso_count = iso_count for plate_label in sorted(self.__prep_positions.keys()): try: value_parts = LABELS.parse_rack_label(plate_label) except ValueError: # the label is an ISO preparation plate marker role = LABELS.ROLE_PREPARATION_ISO else: role = value_parts[LABELS.MARKER_RACK_ROLE] if role == LABELS.ROLE_PREPARATION_JOB: self.__job_plate_labels.add(plate_label)
def __compare_iso_preparation_layouts(self): # If we have starting wells for the job in ISO preparation plates and # more than one ISO in the job, we need to remove duplicates (to avoid # generation of duplicate transfers in stock worklists). # We store the layout of a reference plate (using the label of this # plate as key). Plate containers are stored for all plates. position_map = dict() reference_plates = dict() reference_layouts = dict() for iso in self.entity.isos: if self.has_errors(): break for ipp in iso.iso_preparation_plates: plate = ipp.rack plate_label = plate.label value_parts = LABELS.parse_rack_label(plate_label) rack_marker = value_parts[LABELS.MARKER_RACK_MARKER] self._store_rack_container(rack=plate, label=plate_label, rack_marker=rack_marker, role=LABELS.ROLE_PREPARATION_ISO) converter = LabIsoPrepLayoutConverter( rack_layout=ipp.rack_layout, parent=self) layout = converter.get_result() if layout is None: msg = 'Error when trying to convert ISO preparation ' \ 'plate layout for plate "%s".' % (plate_label) self.add_error(msg) break positions = [] for prep_pos in layout.get_sorted_working_positions(): if prep_pos.is_fixed and prep_pos.is_starting_well: positions.append(prep_pos) if not position_map.has_key(rack_marker): position_map[rack_marker] = positions reference_plates[rack_marker] = plate reference_layouts[rack_marker] = layout elif not position_map[rack_marker] == positions: msg = 'The ISO preparation plates for rack type "%s" are ' \ 'inconsistent!' % (rack_marker) self.add_error(msg) break for rack_marker, plate in reference_plates.iteritems(): layout = reference_layouts[rack_marker] self._plate_layouts[plate.label] = layout
def __compare_iso_preparation_layouts(self): # If we have starting wells for the job in ISO preparation plates and # more than one ISO in the job, we need to remove duplicates (to avoid # generation of duplicate transfers in stock worklists). # We store the layout of a reference plate (using the label of this # plate as key). Plate containers are stored for all plates. position_map = dict() reference_plates = dict() reference_layouts = dict() for iso in self.entity.isos: if self.has_errors(): break for ipp in iso.iso_preparation_plates: plate = ipp.rack plate_label = plate.label value_parts = LABELS.parse_rack_label(plate_label) rack_marker = value_parts[LABELS.MARKER_RACK_MARKER] self._store_rack_container(rack=plate, label=plate_label, rack_marker=rack_marker, role=LABELS.ROLE_PREPARATION_ISO) converter = LabIsoPrepLayoutConverter( rack_layout=ipp.rack_layout, parent=self) layout = converter.get_result() if layout is None: msg = 'Error when trying to convert ISO preparation ' \ 'plate layout for plate "%s".' % (plate_label) self.add_error(msg) break positions = [] for prep_pos in layout.get_sorted_working_positions(): if prep_pos.is_fixed and prep_pos.is_starting_well: positions.append(prep_pos) if not position_map.has_key(rack_marker): position_map[rack_marker] = positions reference_plates[rack_marker] = plate reference_layouts[rack_marker] = layout elif not position_map[rack_marker] == positions: msg = 'The ISO preparation plates for rack type "%s" are ' \ 'inconsistent!' % (rack_marker) self.add_error(msg) break for rack_marker, plate in reference_plates.iteritems(): layout = reference_layouts[rack_marker] self._plate_layouts[plate.label] = layout
def _store_and_verify_plate(self, iso_plate, layout=None, verify=True): """ Convenience method verifying and storing the plate as rack container in the :attr:`_rack_containers` map (mapped onto the rack marker). If the expected ISO status is queued all plates must be empty, otherwise we need a :class:`LabIsoPlateVerifier`. """ plate = iso_plate.rack rack_name = '%s (%s)' % (plate.barcode, plate.label) if self._expected_iso_status == ISO_STATUS.QUEUED and verify: sample_positions = [] for well in plate.containers: if well.sample is not None: if layout is not None: ip = layout.get_working_position(well.position) if ip is not None and ip.is_library: continue sample_positions.append(well.position.label) if len(sample_positions) > 0: msg = 'Plate %s should be empty but there are samples in ' \ 'the following positions: %s.' \ % (plate.label, self._get_joined_str(sample_positions)) self.add_error(msg) return None if not isinstance(iso_plate, (IsoAliquotPlate, LibraryPlate)): converter = LabIsoPrepLayoutConverter(iso_plate.rack_layout, parent=self) layout = converter.get_result() if layout is None: msg = 'Error when trying to convert layout of plate "%s"!' \ % (plate.label) self.add_error(msg) return None else: self.__plate_layouts[plate.label] = layout elif verify: verifier = LabIsoPlateVerifier(iso_plate, self.ENTITY_CLS == IsoJob, lab_iso_layout=layout, parent=self) compatible = verifier.get_result() if compatible is None: msg = 'Error when trying to verify plate %s!' % (rack_name) self.add_error(msg) return None elif not compatible: msg = 'Rack %s does not match the expected layout!' \ % (rack_name) self.add_error(msg) return None elif layout is None: self.__plate_layouts[plate.label] = \ verifier.get_expected_layout() iso = None if self._processing_order == LAB_ISO_ORDERS.NO_ISO and \ isinstance(iso_plate, LibraryPlate): rack_marker = LABELS.ROLE_FINAL iso = iso_plate.lab_iso else: values = LABELS.parse_rack_label(plate.label) rack_marker = values[LABELS.MARKER_RACK_MARKER] rack_container = IsoRackContainer(rack=plate, rack_marker=rack_marker) if rack_container.role == LABELS.ROLE_FINAL: rack_marker = LABELS.ROLE_FINAL if iso is None: iso = iso_plate.iso add_list_map_element(self.__final_plates, iso, rack_container) add_list_map_element(self.__rack_containers, rack_marker, rack_container)
def _store_and_verify_plate(self, iso_plate, layout=None, verify=True): """ Convenience method verifying and storing the plate as rack container in the :attr:`_rack_containers` map (mapped onto the rack marker). If the expected ISO status is queued all plates must be empty, otherwise we need a :class:`LabIsoPlateVerifier`. """ plate = iso_plate.rack rack_name = '%s (%s)' % (plate.barcode, plate.label) if self._expected_iso_status == ISO_STATUS.QUEUED and verify: sample_positions = [] for well in plate.containers: if well.sample is not None: if layout is not None: ip = layout.get_working_position(well.position) if ip is not None and ip.is_library: continue sample_positions.append(well.position.label) if len(sample_positions) > 0: msg = 'Plate %s should be empty but there are samples in ' \ 'the following positions: %s.' \ % (plate.label, self._get_joined_str(sample_positions)) self.add_error(msg) return None if not isinstance(iso_plate, (IsoAliquotPlate, LibraryPlate)): converter = LabIsoPrepLayoutConverter(iso_plate.rack_layout, parent=self) layout = converter.get_result() if layout is None: msg = 'Error when trying to convert layout of plate "%s"!' \ % (plate.label) self.add_error(msg) return None else: self.__plate_layouts[plate.label] = layout elif verify: verifier = LabIsoPlateVerifier(iso_plate, self.ENTITY_CLS == IsoJob, lab_iso_layout=layout, parent=self) compatible = verifier.get_result() if compatible is None: msg = 'Error when trying to verify plate %s!' % (rack_name) self.add_error(msg) return None elif not compatible: msg = 'Rack %s does not match the expected layout!' \ % (rack_name) self.add_error(msg) return None elif layout is None: self.__plate_layouts[plate.label] = \ verifier.get_expected_layout() iso = None if self._processing_order == LAB_ISO_ORDERS.NO_ISO and \ isinstance(iso_plate, LibraryPlate): rack_marker = LABELS.ROLE_FINAL iso = iso_plate.lab_iso else: values = LABELS.parse_rack_label(plate.label) rack_marker = values[LABELS.MARKER_RACK_MARKER] rack_container = IsoRackContainer(rack=plate, rack_marker=rack_marker) if rack_container.role == LABELS.ROLE_FINAL: rack_marker = LABELS.ROLE_FINAL if iso is None: iso = iso_plate.iso add_list_map_element(self.__final_plates, iso, rack_container) add_list_map_element(self.__rack_containers, rack_marker, rack_container)