def __stock_concentration_match(self, candidate, container, error_list): """ Makes sure tube candidate and stock tube container expect the same stock concentration. """ container_conc = container.get_stock_concentration() candidate_conc = candidate.concentration if not are_equal_values(container_conc, candidate_conc): info = '%s (pool: %i, expected: %s nM, found at tube: %s nM)' \ % (candidate.tube_barcode, candidate.pool_id, get_trimmed_string(container_conc), get_trimmed_string(candidate_conc)) error_list.append(info) return False else: return True
def __check_and_assign_tube_candidates(self): """ Checks whether there is pool for each requested pool and whether volume and concentration match. """ missing_pools = [] invalid_conc = [] invalid_vol = [] for pool, container in self._stock_tube_containers.iteritems(): if not self.__tube_candidates.has_key(pool): missing_pools.append(pool.id) continue candidate = self.__tube_candidates[pool] exp_stock_conc = pool.default_stock_concentration \ * CONCENTRATION_CONVERSION_FACTOR if not are_equal_values(candidate.concentration, exp_stock_conc): info = '%s (pool: %s, expected: %s nM, found: %s nM)' % ( candidate.tube_barcode, pool, get_trimmed_string(exp_stock_conc), get_trimmed_string(candidate.concentration)) invalid_conc.append(info) continue required_vol = STOCK_DEAD_VOLUME \ + container.get_total_required_volume() if is_smaller_than(candidate.volume, required_vol): info = '%s (pool: %s, required: %s ul, found: %s ul)' % ( candidate.tube_barcode, pool, get_trimmed_string(required_vol), get_trimmed_string(candidate.volume)) invalid_vol.append(info) continue container.tube_candidate = candidate if len(missing_pools) > 0: msg = 'Could not find tubes for the following pools: %s.' % ( self._get_joined_str(missing_pools, is_strs=False)) self.add_error(msg) if len(invalid_conc) > 0: msg = 'The concentrations in some tubes do not match the ' \ 'expected ones: %s.' % (self._get_joined_str(invalid_conc)) self.add_error(msg) if len(invalid_vol) > 0: msg = 'The volumes in some tubes (dead volume included) are not ' \ 'sufficient: %s.' % (self._get_joined_str(invalid_vol)) self.add_error(msg)
def __create_tube_candidates(self): """ Checks the tubes in the given racks and converts them into :class:`TubeCandidate` objects. Sample which are not stock samples or do not have a volume are ignored. The number of tubes found must match the number of stock tube containers. """ no_stock_sample = dict() no_sample = dict() num_tubes = 0 for barcode, rack in self._barcode_map.iteritems(): for tube in rack.containers: stock_sample = tube.sample rack_pos = tube.rack_position num_tubes += 1 tube_info = '%s (%s)' % (tube.barcode, rack_pos.label) if stock_sample is None: add_list_map_element(no_sample, barcode, tube_info) continue sample_vol = stock_sample.volume * VOLUME_CONVERSION_FACTOR if are_equal_values(sample_vol, 0): add_list_map_element(no_sample, barcode, tube_info) continue if not isinstance(stock_sample, StockSample): add_list_map_element(no_stock_sample, barcode, tube_info) continue pool = stock_sample.molecule_design_pool tc = TubeCandidate(pool_id=pool.id, rack_barcode=barcode, rack_position=rack_pos, tube_barcode=tube.barcode, concentration=stock_sample.concentration, volume=stock_sample.volume) self.__tube_candidates[pool] = tc if len(no_sample) > 0: rack_strs = [] for barcode in sorted(no_sample.keys()): info_str = '%s (%s)' % (barcode, self._get_joined_str( no_sample[barcode])) rack_strs.append(info_str) msg = 'In some racks there are empty tubes: %s. Please remove ' \ 'them and try again.' % (' -- '.join(rack_strs)) self.add_error(msg) if len(no_stock_sample) > 0: msg = 'The tubes in some of the racks you have specified contain ' \ 'normal samples instead of stock samples. Talk to the ' \ 'IT department, please. Details: %s.' \ % (self._get_joined_map_str(no_stock_sample)) self.add_error(msg) exp_tube_num = len(self._stock_tube_containers) if not self.has_errors() and not exp_tube_num == num_tubes: msg = 'The number of tubes in the racks you have specified (%i) ' \ 'is different from the expected one (%i). Remove all tubes ' \ 'that are not required and add the missing ones or try ' \ 'the generate a new stock rack.' % (num_tubes, exp_tube_num) self.add_error(msg)