Beispiel #1
0
 def _create_planned_liquid_transfers(self):
     """
     Generates the planned container dilutions for the worklist.
     """
     self.add_debug('Generate planned container dilutions ...')
     invalid_dil_factor = dict()
     for rack_pos, tf_pos in self.transfection_layout.iterpositions():
         if tf_pos.is_empty:
             continue
         dil_volume = tf_pos.calculate_reagent_dilution_volume() \
                      / VOLUME_CONVERSION_FACTOR
         ini_dil_factor = TransfectionParameters.\
                             calculate_initial_reagent_dilution(
                             float(tf_pos.reagent_dil_factor))
         if ini_dil_factor <= 1:
             add_list_map_element(invalid_dil_factor,
                                  tf_pos.reagent_dil_factor, rack_pos.label)
             continue
         rdf_str = get_trimmed_string(tf_pos.reagent_dil_factor)
         diluent_info = '%s (%s)' % (tf_pos.reagent_name, rdf_str)
         psd = PlannedSampleDilution.get_entity(volume=dil_volume,
                                        target_position=rack_pos,
                                        diluent_info=diluent_info)
         self._add_planned_transfer(psd)
     if len(invalid_dil_factor) > 0:
         msg = 'Invalid dilution reagent factor for rack positions: %s. ' \
               'The factor would result in an initial dilution factor of ' \
               'less then 1!' % (self._get_joined_map_str(invalid_dil_factor))
         self.add_error(msg)
Beispiel #2
0
 def add_preparation_position(self, plate_label, plate_pos):
     """
     Registers a target preparation position for this stock tube (used later
     to generated planned worklists).
     """
     add_list_map_element(self.__prep_positions, plate_label, plate_pos)
     self.__set_stock_rack_marker(plate_pos)
Beispiel #3
0
    def __find_new_tubes(self):
        """
        Finds tubes for pool that do not have a tube candidate yet.
        """
        self.add_debug('Find tubes for missing pools ...')

        for pool_id in self.__replaced_tube_containers:
            pool = self.__pool_map[pool_id]
            container = self.stock_tube_containers[pool]
            required_volume = self.__volume_map[pool_id]
            query = SinglePoolQuery(
                pool_id=pool_id,
                concentration=container.get_stock_concentration(),
                minimum_volume=required_volume)
            self._run_query(query, None)
            candidates = query.get_query_results()
            while len(candidates) > 0:
                candidate = candidates.pop(0)
                tube_barcode = candidate.tube_barcode
                if candidate.rack_barcode in self.excluded_racks:
                    add_list_map_element(self.__excluded_tubes,
                                         pool_id,
                                         tube_barcode,
                                         as_set=True)
                else:
                    container.tube_candidate = candidate
                    candidate.set_pool(container.pool)
                    break
            if container.tube_candidate is None:
                self.__missing_pools.append(container.pool)
Beispiel #4
0
 def __accept_tube_candidate(self, tube_candidate, conc_mismatch_list,
                             insufficent_vol_map):
     """
     A valid tube container must have a matching concentration,
     contain sufficent volume and must be excluded via the rack barcode.
     Accepted candidates are assigned to the referring containers.
     """
     pool_id = tube_candidate.pool_id
     pool = self.__pool_map[pool_id]
     container = self.stock_tube_containers[pool]
     if not self.__stock_concentration_match(tube_candidate, container,
                                 conc_mismatch_list): return False
     required_vol = self.__volume_map[pool_id] + STOCK_DEAD_VOLUME
     if is_smaller_than(tube_candidate.volume, required_vol):
         params = [tube_candidate.tube_barcode,
                   get_trimmed_string(required_vol),
                   get_trimmed_string(tube_candidate.volume)]
         insufficent_vol_map[pool_id] = params
         return False
     if tube_candidate.rack_barcode in self.excluded_racks:
         add_list_map_element(self.__excluded_tubes, pool_id,
                              tube_candidate.tube_barcode, as_set=True)
         return False
     else:
         tube_candidate.set_pool(container.pool)
         container.tube_candidate = tube_candidate
         return True
Beispiel #5
0
    def __init_step_transfer_codes(self):
        """
        Initialises the transfer codes for a particular step.
        """
        self._current_row = self.__current_step.starting_row + 2

        codes = []
        while not self._end_reached:
            code = self._get_cell_value(self._current_row,
                                        self._CODE_COLUMN_INDEX)
            if code is None: break
            codes.append(code)
            self._step_to_next_row()

        if len(codes) < 1:
            msg = 'There are no codes for step %i!' \
                   % (self.__current_step.number)
            cell_name = self._get_cell_name(
                            self.__current_step.starting_row + 2, 1)
            self._create_error(msg, cell_name)

        # there must be at least one codes, otherwise we would have got an
        # error when looking for the tag definition
        for code in codes: self.__current_step.add_transfer_code(code)

        transfer_tag_def = self.__current_step.transfer_tag_definition
        self._tags.add(transfer_tag_def)
        add_list_map_element(self._tags_by_row,
                         self.__current_step.get_transfer_tag_row_index(),
                         transfer_tag_def)
Beispiel #6
0
 def __accept_tube_candidate(self, tube_candidate, conc_mismatch_list,
                             insufficent_vol_map):
     """
     A valid tube container must have a matching concentration,
     contain sufficent volume and must be excluded via the rack barcode.
     Accepted candidates are assigned to the referring containers.
     """
     pool_id = tube_candidate.pool_id
     pool = self.__pool_map[pool_id]
     container = self.stock_tube_containers[pool]
     if not self.__stock_concentration_match(tube_candidate, container,
                                             conc_mismatch_list):
         return False
     required_vol = self.__volume_map[pool_id] + STOCK_DEAD_VOLUME
     if is_smaller_than(tube_candidate.volume, required_vol):
         params = [
             tube_candidate.tube_barcode,
             get_trimmed_string(required_vol),
             get_trimmed_string(tube_candidate.volume)
         ]
         insufficent_vol_map[pool_id] = params
         return False
     if tube_candidate.rack_barcode in self.excluded_racks:
         add_list_map_element(self.__excluded_tubes,
                              pool_id,
                              tube_candidate.tube_barcode,
                              as_set=True)
         return False
     else:
         tube_candidate.set_pool(container.pool)
         container.tube_candidate = tube_candidate
         return True
Beispiel #7
0
    def __get_sorted_executed_transfers(self, executed_transfers,
                                        target_rack_barcode):
        # Sorts the executed transfer of a worklist by pool and source tube
        # barcode.
        pool_map = dict()
        no_pools = set()
        for elt in executed_transfers:
            rack_pos = elt.target_container.location.position
            ssc_pos = self.stock_sample_creation_layout.get_working_position(
                rack_pos)
            if ssc_pos is None:
                info = '%s (rack %s)' % (rack_pos.label, target_rack_barcode)
                no_pools.add(info)
                continue
            pool = ssc_pos.pool
            add_list_map_element(pool_map, pool, elt)

        if len(no_pools) > 0:
            msg = 'Could not find molecule design pools for the following ' \
                  'target positions: %s.' % (self._get_joined_str(no_pools))
            self.add_error(msg)

        for pool, elts in pool_map.iteritems():
            elts.sort(cmp=lambda elt1, elt2: cmp(
                elt1.source_container.barcode, elt2.source_container.barcode))
        return pool_map
Beispiel #8
0
 def _create_planned_liquid_transfers(self):
     """
     Generates the planned container dilutions for the worklist.
     """
     self.add_debug('Generate planned container dilutions ...')
     invalid_dil_factor = dict()
     for rack_pos, tf_pos in self.transfection_layout.iterpositions():
         if tf_pos.is_empty:
             continue
         dil_volume = tf_pos.calculate_reagent_dilution_volume() \
                      / VOLUME_CONVERSION_FACTOR
         ini_dil_factor = TransfectionParameters.\
                             calculate_initial_reagent_dilution(
                             float(tf_pos.reagent_dil_factor))
         if ini_dil_factor <= 1:
             add_list_map_element(invalid_dil_factor,
                                  tf_pos.reagent_dil_factor, rack_pos.label)
             continue
         rdf_str = get_trimmed_string(tf_pos.reagent_dil_factor)
         diluent_info = '%s (%s)' % (tf_pos.reagent_name, rdf_str)
         psd = PlannedSampleDilution.get_entity(volume=dil_volume,
                                                target_position=rack_pos,
                                                diluent_info=diluent_info)
         self._add_planned_transfer(psd)
     if len(invalid_dil_factor) > 0:
         msg = 'Invalid dilution reagent factor for rack positions: %s. ' \
               'The factor would result in an initial dilution factor of ' \
               'less then 1!' % (self._get_joined_map_str(invalid_dil_factor))
         self.add_error(msg)
Beispiel #9
0
 def _store_result(self, result_record):
     """
     Results are converted into :class:`CANDIDATE_CLS` objects before
     storage. The
     """
     candidate = self._create_candidate_from_query_result(result_record)
     add_list_map_element(self._results, candidate.pool_id, candidate)
Beispiel #10
0
 def __get_sorted_executed_transfers(self, executed_liquid_transfers, stock_rack_layout, rack_barcode):
     # Sorts executed transfer of a worklist by molecule design pool ID.
     pool_map = dict()
     no_pools = set()
     for elt in executed_liquid_transfers:
         rack_pos = elt.planned_liquid_transfer.source_position
         sr_pos = stock_rack_layout.get_working_position(rack_pos)
         if sr_pos is None:
             no_pools.add(rack_pos.label)
             continue
         pool_id = sr_pos.molecule_design_pool.id
         add_list_map_element(pool_map, pool_id, elt)
     if len(no_pools) > 0:
         msg = "Could not find molecule design pools for the following " "source positions in rack %s: %s." % (
             rack_barcode,
             self._get_joined_str(no_pools, is_strs=False),
         )
         self.add_error(msg)
     else:
         for elts in pool_map.values():
             elts.sort(
                 cmp=lambda elt1, elt2: cmp(
                     elt1.planned_liquid_transfer.target_position, elt2.planned_liquid_transfer.target_position
                 )
             )
             elts.sort(
                 cmp=lambda elt1, elt2: cmp(elt1.target_container.rack.barcode, elt2.target_container.rack.barcode)
             )
     return pool_map
Beispiel #11
0
 def __get_sorted_executed_transfers(self, executed_liquid_transfers,
                                     stock_rack_layout, rack_barcode):
     # Sorts executed transfer of a worklist by molecule design pool ID.
     pool_map = dict()
     no_pools = set()
     for elt in executed_liquid_transfers:
         rack_pos = elt.planned_liquid_transfer.source_position
         sr_pos = stock_rack_layout.get_working_position(rack_pos)
         if sr_pos is None:
             no_pools.add(rack_pos.label)
             continue
         pool_id = sr_pos.molecule_design_pool.id
         add_list_map_element(pool_map, pool_id, elt)
     if len(no_pools) > 0:
         msg = 'Could not find molecule design pools for the following ' \
               'source positions in rack %s: %s.' % (rack_barcode,
               self._get_joined_str(no_pools, is_strs=False))
         self.add_error(msg)
     else:
         for elts in pool_map.values():
             elts.sort(cmp=lambda elt1, elt2: cmp(
                 elt1.planned_liquid_transfer.target_position, elt2.
                 planned_liquid_transfer.target_position))
             elts.sort(cmp=lambda elt1, elt2: cmp(
                 elt1.target_container.rack.barcode, elt2.target_container.
                 rack.barcode))
     return pool_map
Beispiel #12
0
 def _store_candidate_data(self, candidate):
     """
     Stores the candidate in the :attr:`_picked_candidates` map. Subclasses
     may filter candidates here, too.
     """
     pool = self._pool_map[candidate.pool_id]
     add_list_map_element(self._picked_candidates, pool, candidate)
Beispiel #13
0
    def __find_new_tubes(self):
        """
        Finds tubes for pool that do not have a tube candidate yet.
        """
        self.add_debug('Find tubes for missing pools ...')

        for pool_id in self.__replaced_tube_containers:
            pool = self.__pool_map[pool_id]
            container = self.stock_tube_containers[pool]
            required_volume = self.__volume_map[pool_id]
            query = SinglePoolQuery(pool_id=pool_id,
                            concentration=container.get_stock_concentration(),
                            minimum_volume=required_volume)
            self._run_query(query, None)
            candidates = query.get_query_results()
            while len(candidates) > 0:
                candidate = candidates.pop(0)
                tube_barcode = candidate.tube_barcode
                if candidate.rack_barcode in self.excluded_racks:
                    add_list_map_element(self.__excluded_tubes, pool_id,
                                         tube_barcode, as_set=True)
                else:
                    container.tube_candidate = candidate
                    candidate.set_pool(container.pool)
                    break
            if container.tube_candidate is None:
                self.__missing_pools.append(container.pool)
Beispiel #14
0
 def __find_relationships(self, layout, tool, record_errors):
     # Sets up the association data (if there is more than one
     # concentration).
     # :raises ValueError: If the association fails.
     associator = self._init_associator(layout, tool)
     if not record_errors:
         associator.disable_error_and_warning_recording()
     self._associated_sectors = associator.get_result()
     if self._associated_sectors is None:
         if record_errors:
             msg = '-- '.join(associator.get_messages())
         else:
             msg = 'Error when trying to find rack sector association.'
         raise ValueError(msg)
     self._sector_concentrations = associator.get_sector_concentrations()
     del_sectors = []
     for sector_index, conc in self._sector_concentrations.iteritems():
         if conc is None: del_sectors.append(sector_index)
     for sector_index in del_sectors:
         del self._sector_concentrations[sector_index]
     for sectors in self._associated_sectors:
         # concentrations for associated sectors
         concentrations_map = dict()
         for sector_index in sectors:
             conc = self._sector_concentrations[sector_index]
             add_list_map_element(concentrations_map, conc, sector_index)
         concentrations = sorted(concentrations_map.keys())
         last_sector = None
         for conc in concentrations:
             sectors = concentrations_map[conc]
             for sector_index in sorted(sectors, reverse=True):
                 if not last_sector is None:
                     self._parent_sectors[last_sector] = sector_index
                 last_sector = sector_index
                 self._parent_sectors[sector_index] = None
Beispiel #15
0
 def _store_candidate_data(self, candidate):
     """
     Stores the candidate in the :attr:`_picked_candidates` map. Subclasses
     may filter candidates here, too.
     """
     pool = self._pool_map[candidate.pool_id]
     add_list_map_element(self._picked_candidates, pool, candidate)
Beispiel #16
0
 def _store_result(self, result_record):
     """
     Results are converted into :class:`CANDIDATE_CLS` objects before
     storage. The
     """
     candidate = self._create_candidate_from_query_result(result_record)
     add_list_map_element(self._results, candidate.pool_id, candidate)
Beispiel #17
0
 def add_preparation_position(self, plate_label, plate_pos):
     """
     Registers a target preparation position for this stock tube (used later
     to generated planned worklists).
     """
     add_list_map_element(self.__prep_positions, plate_label, plate_pos)
     self.__set_stock_rack_marker(plate_pos)
Beispiel #18
0
    def __get_sorted_executed_transfers(self, executed_transfers,
                                        target_rack_barcode):
        # Sorts the executed transfer of a worklist by molecule design pool
        # ID.
        pool_map = dict()
        no_pools = set()
        for et in executed_transfers:
            translator = self.__get_translator(target_rack_barcode)
            if translator is None: return None
            rack_pos_96 = et.target_container.location.position
            rack_pos_384 = translator.translate(rack_pos_96)

            lib_pos = self.library_layout.get_working_position(rack_pos_384)
            if lib_pos is None:
                info = '%s (rack %s)' % (rack_pos_96.label, target_rack_barcode)
                no_pools.add(info)
                continue
            pool = lib_pos.pool
            add_list_map_element(pool_map, pool, et)
        if len(no_pools) > 0:
            no_pools_list = list(no_pools)
            no_pools_list.sort()
            msg = 'Could not find molecule design pools for the following ' \
                  'target positions: %s.' % (no_pools_list)
            self.add_error(msg)
        return pool_map
Beispiel #19
0
    def __get_tube_candidates_for_tubes(self, tube_barcodes, tube_type):
        """
        As far as possible we use the tube aggregate to fetch tubes from the
        DB. The tubes for the barcodes are converted into :class:`TubeCandidate`
        objects and mapped onto pools.
        Valid tubes must contain stock samples and be managed.
        """
        self.__tube_agg.filter = cntd(barcode=tube_barcodes)
        iterator = self.__tube_agg.iterator()
        candidate_map = dict()
        no_stock_sample = []
        not_managed = []
        while True:
            try:
                tube = iterator.next()
            except StopIteration:
                break
            else:
                if not tube.item_status == ITEM_STATUS_NAMES.MANAGED.upper():
                    not_managed.append(tube.barcode)
                    continue
                sample = tube.sample
                if not isinstance(sample, StockSample):
                    no_stock_sample.append(tube.barcode)
                    continue
                pool = sample.molecule_design_pool
                tc = TubeCandidate(pool_id=pool.id,
                                   rack_barcode=tube.location.rack.barcode,
                                   rack_position=tube.location.position,
                                   tube_barcode=tube.barcode,
                                   concentration=sample.concentration,
                                   volume=sample.volume)
                # we could store the pool itself to (instead of its ID), but
                # for some reason the pool entities are not recognised as equal
                add_list_map_element(candidate_map, pool.id, tc)
                self.__tube_map[tube.barcode] = tube

        if len(no_stock_sample) > 0:
            msg = 'The following %s tubes do not contain stock ' \
                  'samples: %s! The referring tubes are replaced, if ' \
                  'possible.' % (tube_type,
                                 self._get_joined_str(no_stock_sample))
            self.add_warning(msg)
        if len(not_managed) > 0:
            msg = 'The following %s tubes are not managed: %s. They ' \
                  'are replaced, if possible.' \
                   % (tube_type, self._get_joined_str(not_managed))
            self.add_warning(msg)

        not_found = []
        for tube_barcode in tube_barcodes:
            if not self.__tube_map.has_key(tube_barcode):
                not_found.append(tube_barcode)
        if len(not_found) > 0:
            msg = 'The following %s tubes have not been found in the DB: %s.' \
                  % (tube_type, self._get_joined_str(not_found))
            self.add_warning(msg)

        return candidate_map
Beispiel #20
0
    def __get_tube_candidates_for_tubes(self, tube_barcodes, tube_type):
        """
        As far as possible we use the tube aggregate to fetch tubes from the
        DB. The tubes for the barcodes are converted into :class:`TubeCandidate`
        objects and mapped onto pools.
        Valid tubes must contain stock samples and be managed.
        """
        self.__tube_agg.filter = cntd(barcode=tube_barcodes)
        iterator = self.__tube_agg.iterator()
        candidate_map = dict()
        no_stock_sample = []
        not_managed = []
        while True:
            try:
                tube = iterator.next()
            except StopIteration:
                break
            else:
                if not tube.item_status == ITEM_STATUS_NAMES.MANAGED.upper():
                    not_managed.append(tube.barcode)
                    continue
                sample = tube.sample
                if not isinstance(sample, StockSample):
                    no_stock_sample.append(tube.barcode)
                    continue
                pool = sample.molecule_design_pool
                tc = TubeCandidate(pool_id=pool.id,
                                   rack_barcode=tube.location.rack.barcode,
                                   rack_position=tube.location.position,
                                   tube_barcode=tube.barcode,
                                   concentration=sample.concentration,
                                   volume=sample.volume)
                # we could store the pool itself to (instead of its ID), but
                # for some reason the pool entities are not recognised as equal
                add_list_map_element(candidate_map, pool.id, tc)
                self.__tube_map[tube.barcode] = tube

        if len(no_stock_sample) > 0:
            msg = 'The following %s tubes do not contain stock ' \
                  'samples: %s! The referring tubes are replaced, if ' \
                  'possible.' % (tube_type,
                                 self._get_joined_str(no_stock_sample))
            self.add_warning(msg)
        if len(not_managed) > 0:
            msg = 'The following %s tubes are not managed: %s. They ' \
                  'are replaced, if possible.' \
                   % (tube_type, self._get_joined_str(not_managed))
            self.add_warning(msg)

        not_found = []
        for tube_barcode in tube_barcodes:
            if not self.__tube_map.has_key(tube_barcode):
                not_found.append(tube_barcode)
        if len(not_found) > 0:
            msg = 'The following %s tubes have not been found in the DB: %s.' \
                  % (tube_type, self._get_joined_str(not_found))
            self.add_warning(msg)

        return candidate_map
Beispiel #21
0
 def add_tagged_position(self, tag_predicate, tag_value, cell_indices):
     """
     Stores the tag data in the :attr:`tag_data` map.
     """
     tag_container = TagParsingContainer(parser=self._parser,
                                 predicate=tag_predicate, value=tag_value)
     rack_pos_container = self.get_rack_position_container(cell_indices)
     add_list_map_element(self.tag_data, tag_container, rack_pos_container)
Beispiel #22
0
 def __store_worklist_roles(self, worklist, role, ror):
     # Sets the passed RackOrReservoirItem as source or target for the
     # given worklist.
     if self.__transfer_roles.has_key(worklist.label):
         role_map = self.__transfer_roles[worklist.label]
     else:
         role_map = dict()
         self.__transfer_roles[worklist.label] = role_map
     add_list_map_element(role_map, role, ror)
Beispiel #23
0
 def __create_pool_candidates(self):
     # Initialises empty pool candidates (without stock sample data and
     #candidates) for every pool to be generate.
     self.add_debug('Initialise library candidates ...')
     for pool in self.molecule_design_pools:
         pool_cand = PoolCandidate(pool)
         self.__pool_candidates[pool.id] = pool_cand
         for md_id in pool_cand.get_molecule_design_ids():
             add_list_map_element(self.__md_map, md_id, pool.id)
Beispiel #24
0
 def __store_worklist_roles(self, worklist, role, ror):
     # Sets the passed RackOrReservoirItem as source or target for the
     # given worklist.
     if self.__transfer_roles.has_key(worklist.label):
         role_map = self.__transfer_roles[worklist.label]
     else:
         role_map = dict()
         self.__transfer_roles[worklist.label] = role_map
     add_list_map_element(role_map, role, ror)
Beispiel #25
0
 def add_tagged_position(self, tag_predicate, tag_value, cell_indices):
     """
     Stores the tag data in the :attr:`tag_data` map.
     """
     tag_container = TagParsingContainer(parser=self._parser,
                                         predicate=tag_predicate,
                                         value=tag_value)
     rack_pos_container = self.get_rack_position_container(cell_indices)
     add_list_map_element(self.tag_data, tag_container, rack_pos_container)
Beispiel #26
0
 def plate_target_positions(self):
     """
     Returns the target positions mapped onto plate labels. The plate
     label for the final layout is :attr:`LAEBLS.ROLE_FINAL`.
     """
     target_positions = dict()
     if len(self.__final_positions) > 0:
         for final_pos in self.__final_positions:
             add_list_map_element(target_positions, LABELS.ROLE_FINAL,
                                  final_pos)
     target_positions.update(self.__prep_positions)
     return target_positions
Beispiel #27
0
    def add_worklist(self, role, worklist):
        """
        Registers a worklist in which this object takes over the specified
        role.

        :param role: source or target
            (see :class:`thelma.tools.worklists.TRANSFER_ROLES`)
        :type role: :class:`str`
        :param worklist: a worklist in which this rack or reservoir occurs
        :type worklist: :class:`thelma.entities.liquidtransfer.PlannedWorklist`
        """
        add_list_map_element(self.__worklists, role, worklist)
Beispiel #28
0
    def add_position(self, role, pos_container):
        """
        Adds the position to the position list of the given role.

        :param role: source or target
            (see :class:`TransferStepParsingContainer`)
        :type role: :class:`str`

        :param pos_container: The position to store
        :type pos_container: :class:`RackPositionParsingContainer`
        """
        add_list_map_element(self.positions, role, pos_container)
Beispiel #29
0
 def plate_target_positions(self):
     """
     Returns the target positions mapped onto plate labels. The plate
     label for the final layout is :attr:`LAEBLS.ROLE_FINAL`.
     """
     target_positions = dict()
     if len(self.__final_positions) > 0:
         for final_pos in self.__final_positions:
             add_list_map_element(target_positions, LABELS.ROLE_FINAL,
                                  final_pos)
     target_positions.update(self.__prep_positions)
     return target_positions
Beispiel #30
0
    def __create_library_candidates(self):
        """
        Initialises empty library candidates (without stock sample data and
        candidates) for every library pool.
        """
        self.add_debug('Initialise library candidates ...')

        for pool in self.molecule_design_pools:
            libcand = LibraryCandidate(pool)
            self.__library_candidates[pool.id] = libcand
            for md_id in libcand.get_molecule_design_ids():
                add_list_map_element(self.__md_map, md_id, pool.id)
    def _find_hash_values(self):
        """
        Initialises :attr:`_hash_values` and :attr:`_column_maps`.
        """
        self.add_debug('Sort hash values ...')

        for label, tf_layout in self.design_rack_layouts.iteritems():
            column_map = dict()
            for tf_pos in tf_layout.get_sorted_working_positions():
                self._hash_values.add(tf_pos.hash_full)
                add_list_map_element(column_map,
                                     tf_pos.rack_position.column_index, tf_pos)
            self._column_maps[label] = column_map
Beispiel #32
0
    def _find_hash_values(self):
        """
        Initialises :attr:`_hash_values` and :attr:`_column_maps`.
        """
        self.add_debug('Sort hash values ...')

        for label, tf_layout in self.design_rack_layouts.iteritems():
            column_map = dict()
            for tf_pos in tf_layout.get_sorted_working_positions():
                self._hash_values.add(tf_pos.hash_full)
                add_list_map_element(column_map,
                                     tf_pos.rack_position.column_index, tf_pos)
            self._column_maps[label] = column_map
Beispiel #33
0
    def __sort_subcolumns(self):
        """
        Sorts the subcolumns by length.
        """
        self.add_debug('Sort subcolumns ...')

        found_before = set()

        for subcolumn in self.__subcolumn_tids.values():
            if subcolumn in found_before: continue
            found_before.add(subcolumn)
            add_list_map_element(self.__subcolumn_lengths, len(subcolumn),
                                 subcolumn)
Beispiel #34
0
    def __get_expected_sector_positions(self):
        """
        Returns the expected position for each pool sorted by sector index.
        """
        inconsistent = []
        contains_non_sectors = False
        has_sectors = False
        expected_positions = dict()

        for pool, container in self._stock_tube_containers.iteritems():
            stock_rack_marker = container.stock_rack_marker
            for plate_label, positions in container.plate_target_positions.\
                                          iteritems():
                plate_layout = self._plate_layouts[plate_label]
                sector_positions = dict()
                for plate_pos in positions:
                    sector_index = plate_pos.sector_index
                    if sector_index is None:
                        contains_non_sectors = True
                        continue
                    elif not has_sectors:
                        has_sectors = True
                    add_list_map_element(sector_positions, sector_index,
                                         plate_pos)
                if len(sector_positions) < 1: continue
                exp_data = self.__get_expected_stock_rack_position(plate_layout,
                                                              sector_positions)
                if exp_data is None:
                    inconsistent.append(pool.id)
                else:
                    sector_index = exp_data[1]
                    self._stock_rack_sectors[stock_rack_marker] = sector_index
                    sector_pools = get_nested_dict(expected_positions,
                                                   sector_index)
                    exp_pos = exp_data[0]
                    sector_pools[pool] = exp_pos

        if contains_non_sectors and has_sectors:
            msg = 'The sector data for the layouts are inconsistent - some ' \
                  'sector indices for samples are None!'
            self.add_error(msg)
            return None
        if inconsistent:
            msg = 'The sector for the following pools are inconsistent ' \
                  'in the layouts: %s.' % (self._get_joined_str(inconsistent,
                                                                is_strs=False))
            self.add_error(msg)
            return None

        return expected_positions
Beispiel #35
0
    def __store_column_values(self):
        # Store the values for the columns.
        self.add_debug('Store values ...')
        source_rack_map = dict()
        for ew in self.executed_worklists:
            for elt in ew:
                source_rack_barcode = elt.source_container.rack.barcode
                add_list_map_element(source_rack_map, source_rack_barcode, elt)
        well_containers = dict()
        missing_layouts = []
        sorted_elts = dict()
        for source_rack_barcode in sorted(source_rack_map.keys()):
            executed_transfers = source_rack_map[source_rack_barcode]
            if not self.stock_rack_data.has_key(source_rack_barcode):
                missing_layouts.append(source_rack_barcode)
                continue
            layout = self.stock_rack_data[source_rack_barcode]
            pool_map = self.__get_sorted_executed_transfers(
                executed_transfers, layout, source_rack_barcode)
            if self.has_errors(): break
            for pool_id, elts in pool_map.iteritems():
                sorted_elts[pool_id] = elts
        for pool_id in sorted(sorted_elts.keys()):
            elts = sorted_elts[pool_id]
            for elt in elts:
                self.__pool_values.append(get_trimmed_string(pool_id))
                source_container = elt.source_container
                plt = elt.planned_liquid_transfer
                if not isinstance(source_container, Tube):
                    pos_label = plt.source_position.label
                    add_list_map_element(well_containers,
                                         source_container.rack.barcode,
                                         pos_label)
                    continue
                self.__tube_barcode_values.append(source_container.barcode)
                volume = plt.volume * VOLUME_CONVERSION_FACTOR
                self.__volume_values.append(get_trimmed_string(volume))
                self.__trg_rack_barcode_values.append(
                    elt.target_container.rack.barcode)
                self.__trg_position_values.append(plt.target_position.label)

        if len(well_containers) > 0:
            msg = 'Some source containers in the worklists are wells: %s!' \
                   % (self._get_joined_map_str(well_containers,
                                               'plate %s (positions %s)'))
            self.add_error(msg)
        if len(missing_layouts) > 0:
            msg = 'Unable to find the layouts for the following stock ' \
                  'racks: %s.' % (self._get_joined_str(missing_layouts))
            self.add_error(msg)
Beispiel #36
0
    def __devide_subcolumn(self, subcolumn):
        """
        Devides a subcolumn into 2 parts, of which one stored and the second
        is put pack into the queue.
        """
        ssc = self.__get_column_with_less_positions(len(subcolumn))
        if not ssc is None:

            free_count = len(ssc)
            storage_subcolumn = subcolumn.split(free_count)
            self.__assign_subcolumn_positions(ssc, storage_subcolumn)

            add_list_map_element(self.__subcolumn_lengths, len(subcolumn),
                                 subcolumn)
Beispiel #37
0
    def _create_one_to_one_map(self):
        """
        Creates one position map for one to one sorting (with source rack
        positions as keys and template working positions as values).
        Return *None* if one-to-one sorting is not possible.

        This is some sort of short cut for the very simple layouts.
        In one-to-one sorting mode we simply assign the rack position of the
        earliest occurrence of a design rack transfection position. If the
        position is already occupied, the process is aborted and we switch
        back to the "normal" optimisation algorithm.

        One-to-one assumes equal rack shapes and (almost) equal design racks.
        """
        hash_map = dict()  # rack positions onto hashes
        tf_map = dict()  # tf positions onto rack positions

        abort_sorting = False
        is_first_layout = None
        for tf_layout in self.design_rack_layouts.values():

            if is_first_layout is None:
                is_first_layout = True
            elif is_first_layout:
                is_first_layout = False

            if abort_sorting: break
            for tf_pos in tf_layout.get_sorted_working_positions():
                hash_value = tf_pos.hash_full
                rack_pos = tf_pos.rack_position

                if not hash_map.has_key(hash_value):  # new hash
                    if not tf_map.has_key(rack_pos):  # position available
                        tf_map[rack_pos] = tf_pos
                        add_list_map_element(hash_map, hash_value, rack_pos)
                    else:  # position occupied
                        abort_sorting = True
                        break
                elif is_first_layout:
                    add_list_map_element(hash_map, hash_value, rack_pos)
                elif not rack_pos in hash_map[hash_value]:
                    abort_sorting = True
                    break

        if abort_sorting:
            return None
        else:
            return tf_map
Beispiel #38
0
    def __find_floating_only_associations(self):
        """
        Since all floating are treated in the same way we exclude the
        possibility of equal concentrations in a rack sectors if controls
        are not regarded as in this case we have 2 ways to interpreted
        findings (remember that the floating placeholder have not been
        assigned yet).

        Example: 4 floatings with the same contration can either be regarded
        as 4 independent pools or as 1 pool in 4-fold replicate. As the first
        case is more likely in our company we choose the this case for
        interpretation. If scientists want a different interpretation
        we have to adjust this manually.
        """
        concentrations = dict()
        present_sectors = []
        for sector_index, conc in self._sector_concentrations.iteritems():
            if conc is not None:
                add_list_map_element(concentrations, conc, sector_index)
                present_sectors.append(sector_index)
        if len(self._associated_sectors) > 1:
            msg = 'Unable to adjust floating position association ' \
                  'because basic assumptions are not met. This is ' \
                  'a programming error. Talk to IT, please.'
            raise AssertionError(msg)

        if len(present_sectors) > 1:
            current_sets = []
            if len(concentrations) == 1:
                for sector_index in present_sectors:
                    current_sets.append([sector_index])
            elif len(concentrations) > 1:
                while len(concentrations) > 0:
                    current_set = []
                    del_conc = []
                    for conc, sectors in concentrations.iteritems():
                        sectors.sort()
                        si = sectors.pop(0)
                        current_set.append(si)
                        if len(sectors) < 1: del_conc.append(conc)
                    current_sets.append(current_set)
                    for conc in del_conc:
                        del concentrations[conc]
        else:
            current_sets = [[present_sectors[0]]]

        if self._are_valid_sets(current_sets):
            self._associated_sectors = current_sets
    def _create_one_to_one_map(self):
        """
        Creates one position map for one to one sorting (with source rack
        positions as keys and template working positions as values).
        Return *None* if one-to-one sorting is not possible.

        This is some sort of short cut for the very simple layouts.
        In one-to-one sorting mode we simply assign the rack position of the
        earliest occurrence of a design rack transfection position. If the
        position is already occupied, the process is aborted and we switch
        back to the "normal" optimisation algorithm.

        One-to-one assumes equal rack shapes and (almost) equal design racks.
        """
        hash_map = dict() # rack positions onto hashes
        tf_map = dict() # tf positions onto rack positions

        abort_sorting = False
        is_first_layout = None
        for tf_layout in self.design_rack_layouts.values():

            if is_first_layout is None:
                is_first_layout = True
            elif is_first_layout:
                is_first_layout = False

            if abort_sorting: break
            for tf_pos in tf_layout.get_sorted_working_positions():
                hash_value = tf_pos.hash_full
                rack_pos = tf_pos.rack_position

                if not hash_map.has_key(hash_value): # new hash
                    if not tf_map.has_key(rack_pos): # position available
                        tf_map[rack_pos] = tf_pos
                        add_list_map_element(hash_map, hash_value, rack_pos)
                    else: # position occupied
                        abort_sorting = True
                        break
                elif is_first_layout:
                    add_list_map_element(hash_map, hash_value, rack_pos)
                elif not rack_pos in hash_map[hash_value]:
                    abort_sorting = True
                    break

        if abort_sorting:
            return None
        else:
            return tf_map
Beispiel #40
0
    def __store_column_values(self):
        # Store the values for the columns.
        self.add_debug("Store values ...")
        source_rack_map = dict()
        for ew in self.executed_worklists:
            for elt in ew:
                source_rack_barcode = elt.source_container.rack.barcode
                add_list_map_element(source_rack_map, source_rack_barcode, elt)
        well_containers = dict()
        missing_layouts = []
        sorted_elts = dict()
        for source_rack_barcode in sorted(source_rack_map.keys()):
            executed_transfers = source_rack_map[source_rack_barcode]
            if not self.stock_rack_data.has_key(source_rack_barcode):
                missing_layouts.append(source_rack_barcode)
                continue
            layout = self.stock_rack_data[source_rack_barcode]
            pool_map = self.__get_sorted_executed_transfers(executed_transfers, layout, source_rack_barcode)
            if self.has_errors():
                break
            for pool_id, elts in pool_map.iteritems():
                sorted_elts[pool_id] = elts
        for pool_id in sorted(sorted_elts.keys()):
            elts = sorted_elts[pool_id]
            for elt in elts:
                self.__pool_values.append(get_trimmed_string(pool_id))
                source_container = elt.source_container
                plt = elt.planned_liquid_transfer
                if not isinstance(source_container, Tube):
                    pos_label = plt.source_position.label
                    add_list_map_element(well_containers, source_container.rack.barcode, pos_label)
                    continue
                self.__tube_barcode_values.append(source_container.barcode)
                volume = plt.volume * VOLUME_CONVERSION_FACTOR
                self.__volume_values.append(get_trimmed_string(volume))
                self.__trg_rack_barcode_values.append(elt.target_container.rack.barcode)
                self.__trg_position_values.append(plt.target_position.label)

        if len(well_containers) > 0:
            msg = "Some source containers in the worklists are wells: %s!" % (
                self._get_joined_map_str(well_containers, "plate %s (positions %s)")
            )
            self.add_error(msg)
        if len(missing_layouts) > 0:
            msg = "Unable to find the layouts for the following stock " "racks: %s." % (
                self._get_joined_str(missing_layouts)
            )
            self.add_error(msg)
Beispiel #41
0
    def __find_floating_only_associations(self):
        """
        Since all floating are treated in the same way we exclude the
        possibility of equal concentrations in a rack sectors if controls
        are not regarded as in this case we have 2 ways to interpreted
        findings (remember that the floating placeholder have not been
        assigned yet).

        Example: 4 floatings with the same contration can either be regarded
        as 4 independent pools or as 1 pool in 4-fold replicate. As the first
        case is more likely in our company we choose the this case for
        interpretation. If scientists want a different interpretation
        we have to adjust this manually.
        """
        concentrations = dict()
        present_sectors = []
        for sector_index, conc in self._sector_concentrations.iteritems():
            if conc is not None:
                add_list_map_element(concentrations, conc, sector_index)
                present_sectors.append(sector_index)
        if len(self._associated_sectors) > 1:
            msg = 'Unable to adjust floating position association ' \
                  'because basic assumptions are not met. This is ' \
                  'a programming error. Talk to IT, please.'
            raise AssertionError(msg)

        if len(present_sectors) > 1:
            current_sets = []
            if len(concentrations) == 1:
                for sector_index in present_sectors:
                    current_sets.append([sector_index])
            elif len(concentrations) > 1:
                while len(concentrations) > 0:
                    current_set = []
                    del_conc = []
                    for conc, sectors in concentrations.iteritems():
                        sectors.sort()
                        si = sectors.pop(0)
                        current_set.append(si)
                        if len(sectors) < 1: del_conc.append(conc)
                    current_sets.append(current_set)
                    for conc in del_conc: del concentrations[conc]
        else:
            current_sets = [[present_sectors[0]]]

        if self._are_valid_sets(current_sets):
            self._associated_sectors = current_sets
Beispiel #42
0
 def _check_associated_sectors(self):
     """
     Sectors sets are sorted by size first. Larger sets must incorporate all
     known smaller sets sharing these sector indices.
     All final sets must have the same length to insure all potential
     floating positions are treated in the same manner.
     """
     length_map = dict()
     for sectors in self.__sector_set_hashes.values():
         add_list_map_element(length_map, len(sectors), sectors)
     current_sets = []
     used_sectors = dict()
     invalid = False
     for length in sorted(length_map.keys()):
         if invalid: break
         sector_sets = length_map[length]
         for sector_set in sector_sets:
             all_new = True
             all_present = True
             for si in sector_set:
                 if not used_sectors.has_key(si):
                     all_present = False
                     used_sectors[si] = sector_set
                 else:
                     all_new = False
             if all_new:
                 current_sets.append(sector_set)
                 continue
             elif not all_present:
                 invalid = True
                 break
             for si in sector_set:
                 smaller_set = used_sectors[si]
                 for smaller_set_index in smaller_set:
                     if not smaller_set_index in sector_set:
                         invalid = True
                         break
     if invalid:
         msg = 'The molecule design pools in the different quadrants are ' \
               'not consistent. Found associated pools: %s.' \
                % (self._get_joined_map_str(self.__sector_set_positions,
                   all_strs=False))
         self.add_error(msg)
     elif self._are_valid_sets(current_sets):
         self._associated_sectors = current_sets
Beispiel #43
0
    def __find_rack_association(self, donor_rack):
        # Initialises a donor rack and finds the receiver racks for it.
        receiver_racks = dict()
        associations = dict()  # receiver barcode, num tubes
        # check
        remaining_tubes = donor_rack.tube_count
        while remaining_tubes > 0:
            receiver = None
            while receiver is None:
                receiver_candidate = self.__find_receiver_rack(remaining_tubes)
                if receiver_candidate is None:
                    break
                if receiver_candidate.rack_barcode in self.excluded_racks:
                    continue
                receiver = receiver_candidate
            if receiver is None:
                return False
            if receiver.role is None:
                occupied_positions = receiver.tube_count
            else:
                occupied_positions = receiver.resulting_tube_count
            free_positions = self.__stock_rack_size - occupied_positions
            transferred_tubes = min(free_positions, remaining_tubes)
            associations[receiver.rack_barcode] = transferred_tubes
            remaining_tubes -= transferred_tubes
            receiver_racks[receiver.rack_barcode] = receiver
        # record
        donor_rack.set_role(STOCK_CONDENSE_ROLES.DONOR)
        for receiver_barcode, num_tubes in associations.iteritems():
            receiver = receiver_racks[receiver_barcode]
            if receiver.role is None:
                receiver.set_role(STOCK_CONDENSE_ROLES.RECEIVER)
            donor_rack.add_rack_association(rack_barcode=receiver_barcode,
                                            number_tubes=num_tubes)
            receiver.add_rack_association(number_tubes=num_tubes,
                                          rack_barcode=donor_rack.rack_barcode)
            self.__receiver_racks[receiver_barcode] = receiver
            resulting_receiver_tubes = receiver.resulting_tube_count
            if resulting_receiver_tubes < self.__stock_rack_size:
                add_list_map_element(self.__tube_count_map,
                                     resulting_receiver_tubes, receiver)

        self.__donor_racks[donor_rack.rack_barcode] = donor_rack
        return True
Beispiel #44
0
    def __find_rack_association(self, donor_rack):
        # Initialises a donor rack and finds the receiver racks for it.
        receiver_racks = dict()
        associations = dict() # receiver barcode, num tubes
        # check
        remaining_tubes = donor_rack.tube_count
        while remaining_tubes > 0:
            receiver = None
            while receiver is None:
                receiver_candidate = self.__find_receiver_rack(remaining_tubes)
                if receiver_candidate is None:
                    break
                if receiver_candidate.rack_barcode in self.excluded_racks:
                    continue
                receiver = receiver_candidate
            if receiver is None:
                return False
            if receiver.role is None:
                occupied_positions = receiver.tube_count
            else:
                occupied_positions = receiver.resulting_tube_count
            free_positions = self.__stock_rack_size - occupied_positions
            transferred_tubes = min(free_positions, remaining_tubes)
            associations[receiver.rack_barcode] = transferred_tubes
            remaining_tubes -= transferred_tubes
            receiver_racks[receiver.rack_barcode] = receiver
        # record
        donor_rack.set_role(STOCK_CONDENSE_ROLES.DONOR)
        for receiver_barcode, num_tubes in associations.iteritems():
            receiver = receiver_racks[receiver_barcode]
            if receiver.role is None:
                receiver.set_role(STOCK_CONDENSE_ROLES.RECEIVER)
            donor_rack.add_rack_association(rack_barcode=receiver_barcode,
                                              number_tubes=num_tubes)
            receiver.add_rack_association(number_tubes=num_tubes,
                                    rack_barcode=donor_rack.rack_barcode)
            self.__receiver_racks[receiver_barcode] = receiver
            resulting_receiver_tubes = receiver.resulting_tube_count
            if resulting_receiver_tubes < self.__stock_rack_size:
                add_list_map_element(self.__tube_count_map,
                                     resulting_receiver_tubes, receiver)

        self.__donor_racks[donor_rack.rack_barcode] = donor_rack
        return True
Beispiel #45
0
 def _store_column_values(self):
     """
     Stores the column values.
     """
     self.add_debug('Store column values ...')
     src_rack_map = dict()
     for tube_transfer in self._tube_transfer_data:
         add_list_map_element(src_rack_map, tube_transfer.src_rack_barcode,
                              tube_transfer)
     src_racks = sorted(src_rack_map.keys())
     for src_rack in src_racks:
         tube_barcodes = sorted(src_rack_map[src_rack],
                                cmp=lambda tt1, tt2: cmp(tt1.tube_barcode,
                                                         tt2.tube_barcode))
         for tube_transfer in tube_barcodes:
             self._source_rack_values.append(src_rack)
             self._source_position_values.append(tube_transfer.src_pos.label)
             self._tube_barcode_values.append(tube_transfer.tube_barcode)
             self._dest_rack_values.append(tube_transfer.trg_rack_barcode)
             self._dest_position_values.append(tube_transfer.trg_pos.label)
Beispiel #46
0
 def _store_column_values(self):
     """
     Stores the column values.
     """
     self.add_debug('Store column values ...')
     src_rack_map = dict()
     for tube_transfer in self._tube_transfer_data:
         add_list_map_element(src_rack_map, tube_transfer.src_rack_barcode,
                              tube_transfer)
     src_racks = sorted(src_rack_map.keys())
     for src_rack in src_racks:
         tube_barcodes = sorted(
             src_rack_map[src_rack],
             cmp=lambda tt1, tt2: cmp(tt1.tube_barcode, tt2.tube_barcode))
         for tube_transfer in tube_barcodes:
             self._source_rack_values.append(src_rack)
             self._source_position_values.append(
                 tube_transfer.src_pos.label)
             self._tube_barcode_values.append(tube_transfer.tube_barcode)
             self._dest_rack_values.append(tube_transfer.trg_rack_barcode)
             self._dest_position_values.append(tube_transfer.trg_pos.label)
Beispiel #47
0
    def __are_valid_transfer_targets(self, transfer_targets, rack_position,
                                     parameter_name):
        """
        Stores the transfer targets and checks their consistency.
        """
        if transfer_targets is None or len(transfer_targets) < 1:
            if self.PARAMETER_SET.must_have_transfer_targets(parameter_name):
                add_list_map_element(self.__missing_transfer_target,
                                     parameter_name, rack_position.label)
                return False
            else:
                return True

        allow_duplicates = self.LAYOUT_CLS.ALLOW_DUPLICATE_TARGET_WELLS[
                                                            parameter_name]
        for transfer_target in transfer_targets:
            if not allow_duplicates and transfer_target.hash_value \
                                in self._transfer_targets[parameter_name]:
                error_msg = '%s' % (transfer_target)
                add_list_map_element(self.__duplicate_targets, parameter_name,
                                     error_msg)
                return False
            else:
                add_list_map_element(self._transfer_targets, parameter_name,
                                     transfer_target.hash_value)

        return True
Beispiel #48
0
    def __fetch_rack_locations(self):
        """
        Searches and adds the location for the selected candidates.
        """
        self.add_debug('Fetch stock rack locations ...')

        rack_barcodes = dict()
        for container in self.stock_tube_containers.values():
            if container.tube_candidate is None: continue
            rack_barcode = container.tube_candidate.rack_barcode
            add_list_map_element(rack_barcodes, rack_barcode, container)

        query = None
        if len(rack_barcodes) > 0:
            query = RackLocationQuery(rack_barcodes=rack_barcodes.keys())
            self._run_query(query, base_error_msg='Error when trying to ' \
                                                  'fetch rack locations: ')
        if not self.has_errors() and not query is None:
            results = query.get_query_results()
            for rack_barcode, location in results.iteritems():
                for container in rack_barcodes[rack_barcode]:
                    container.location = location
Beispiel #49
0
    def __fetch_rack_locations(self):
        """
        Searches and adds the location for the selected candidates.
        """
        self.add_debug('Fetch stock rack locations ...')

        rack_barcodes = dict()
        for container in self.stock_tube_containers.values():
            if container.tube_candidate is None: continue
            rack_barcode = container.tube_candidate.rack_barcode
            add_list_map_element(rack_barcodes, rack_barcode, container)

        query = None
        if len(rack_barcodes) > 0:
            query = RackLocationQuery(rack_barcodes=rack_barcodes.keys())
            self._run_query(query, base_error_msg='Error when trying to ' \
                                                  'fetch rack locations: ')
        if not self.has_errors() and not query is None:
            results = query.get_query_results()
            for rack_barcode, location in results.iteritems():
                for container in rack_barcodes[rack_barcode]:
                    container.location = location
Beispiel #50
0
    def _parse_target_tag_value(self, target_tag_value, rack_position,
                                parameter_name):
        """
        Converts the value of a target tag into a TargetTransfer List.
        """
        if target_tag_value is None:
            transfer_targets = []
        else:
            try:
                transfer_targets = TransferPosition.parse_target_tag_value(
                                                        target_tag_value)
            except ValueError:
                error_msg = '"%s" (%s)' % (target_tag_value, rack_position.label)
                add_list_map_element(self.__invalid_target_string, parameter_name,
                                     error_msg)
                return None

        if not self.__are_valid_transfer_targets(transfer_targets,
                                     rack_position, parameter_name):
            return None

        return transfer_targets
Beispiel #51
0
 def __get_sorted_executed_transfers(self, executed_transfers,
                                     target_rack_barcode):
     # Sorts the executed transfer of a worklist by molecule design pool
     # ID.
     pool_map = dict()
     no_pools = set()
     for et in executed_transfers:
         ssc_layout = self.__ssc_layout_map[et.source_rack.barcode]
         rack_pos = et.target_container.location.position
         ssc_pos = ssc_layout.get_working_position(rack_pos)
         if ssc_pos is None:
             info = '%s (rack %s)' % (rack_pos.label, target_rack_barcode)
             no_pools.add(info)
             continue
         pool = ssc_pos.pool
         add_list_map_element(pool_map, pool, et)
     if len(no_pools) > 0:
         msg = 'Could not find molecule design pools for the following ' \
               'target positions: %s.' % (self._get_joined_str(no_pools))
         self.add_error(msg)
     for ets in pool_map.itervalues():
         ets.sort(key=lambda et: et.source_container.barcode)
     return pool_map
Beispiel #52
0
    def __check_numerical_values(self, value_maps, label):
        """
        Checks the values of the numerical parameters.
        """
        invalid_numericals = dict()
        invalid_mock = dict()
        invalid_untreated = dict()

        pool_map = value_maps[TransfectionParameters.MOLECULE_DESIGN_POOL]
        for parameter, value_map in value_maps.iteritems():
            if not parameter in _SCENARIO_PARAMETERS.NUMERICAL_PARAMETERS:
                continue
            for rack_pos, value in value_map.iteritems():
                if value is None: continue

                pool = pool_map[rack_pos]

                if (pool == MOCK_POSITION_TYPE):
                    if not TransfectionParameters.is_valid_mock_value(
                            value, parameter):
                        add_list_map_element(invalid_mock, parameter,
                                             rack_pos.label)

                elif TransfectionParameters.is_untreated_type(pool):
                    if parameter in (TransfectionParameters.FINAL_CONCENTRATION,
                                TransfectionParameters.REAGENT_DIL_FACTOR) \
                                and not TransfectionPosition.\
                                        is_valid_untreated_value(value):
                        add_list_map_element(invalid_untreated, parameter,
                                             rack_pos.label)

                elif not is_valid_number(value):
                    info = '%s (%s)' % (rack_pos.label, value)
                    add_list_map_element(invalid_numericals, parameter, info)

        if len(invalid_numericals) > 0:
            records_str = self.__get_error_record_string(invalid_numericals)
            msg = 'The levels of some factors must be positive numbers. The ' \
                  'following positions in design rack %s have invalid ' \
                  'values: %s.' % (label, records_str)
            self.add_error(msg)

        if len(invalid_mock) > 0:
            records_str = self.__get_error_record_string(invalid_mock)
            msg = 'The levels of some factors for mock positions allow only ' \
                  'for the values "None" or "mock" (or no level). Some ' \
                  'positions in design rack "%s" have invalid levels. ' \
                  'Affected positions: %s.' % (label, records_str)
            self.add_error(msg)

        if len(invalid_untreated) > 0:
            records_str = self.__get_error_record_string(invalid_untreated)
            msg = 'The levels of some factors for untreated positions allow ' \
                  'only for the values "None" and "untreated" (or no level). ' \
                  'Some position in design rack "%s" have invalid levels. ' \
                  'Affected positions: %s.' % (label, records_str)
            self.add_error(msg)
Beispiel #53
0
 def __run_association_round(self):
     # Runs one association round.
     while len(self.__tube_count_map) > 0:
         if self.__stop_associations: break
         if not self.racks_to_empty is None and \
                     len(self.__donor_racks) >= self.racks_to_empty:
             self.__stop_associations = True
             break
         tube_counts = self.__tube_count_map.keys()
         tube_counts.sort()
         tube_count = tube_counts[0]
         if tube_count > (self.__stock_rack_size / 2):
             break
         condense_racks = self.__tube_count_map[tube_count]
         potential_donor = condense_racks.pop()
         if len(condense_racks) == 0:
             del self.__tube_count_map[tube_count]
         if potential_donor.rack_barcode in self.excluded_racks:
             continue
         found_associations = self.__find_rack_association(potential_donor)
         if not found_associations:
             add_list_map_element(self.__tube_count_map, tube_count,
                                  potential_donor)
             break