示例#1
0
class LibraryCreationTubePicker(BaseTool):
    """
    Runs the optimization query for the given set of molecule designs.
    The tool also picks tubes.

    **Return Value:** the :class:`LibraryCandidate` objects in the order
        of completion
    """
    NAME = 'Library Creation Optimizer'

    def __init__(self, molecule_design_pools, stock_concentration,
                 take_out_volume,
                 excluded_racks=None, requested_tubes=None, parent=None):
        """
        Constructor.

        :param molecule_design_pools: The molecule design pool IDs for which
            to run the query.
        :type molecule_design_pools: :class:`set` of molecule design pool IDs
        :param int stock_concentration: The stock concentration of the single
            molecule design pools for the library in nM (positive number).
        :param int take_out_volume: The volume that shall be removed from the
            single molecule design stock in ul (positive number).
        :param requested_tubes: A list of barcodes from stock tubes that are
            supposed to be used.
        :type requested_tubes: A list of tube barcodes.
        :param excluded_racks: A list of barcodes from stock racks that shall
            not be used for molecule design picking.
        :type excluded_racks: A list of rack barcodes
        """
        BaseTool.__init__(self, parent=parent)
        #: The molecule design pool IDs for which to run the query.
        self.molecule_design_pools = molecule_design_pools
        #: The stock concentration of the single molecule design pools for
        #: the library in nM.
        self.stock_concentration = stock_concentration
        #: The volume that shall be removed from the single molecule design
        #: stock in ul.
        self.take_out_volume = take_out_volume
        if excluded_racks is None: excluded_racks = []
        #: A list of barcodes from stock racks that shall not be used for
        #: molecule design picking.
        self.excluded_racks = excluded_racks
        if requested_tubes is None: requested_tubes = []
        #: A list of barcodes from stock tubes that are supposed to be used
        #: (for fixed positions).
        self.requested_tubes = requested_tubes
        #: The DB session used for the queries.
        self.__session = None
        #: The library candidated mapped onto pool IDs.
        self.__library_candidates = None
        #: Maps library pool IDs onto molecule design IDs. ATTENTION: a molecule
        #: design pool can point to several library pools! For this reason,
        #: library pool IDs are stored in lists.
        self.__md_map = None
        #: Maps molecule design IDs onto single molecule design pool IDs.
        self.__single_pool_map = None
        #: Stores the suitable stock sample IDs for the single molecule
        #: designs pools used to create the library pools. The results are
        #: determined by the :class:`SINGLE_POOL_QUERY`.
        self.__stock_samples = None

        #: The picked library candidates for the pools in the order of
        #: completion.
        self.__picked_candidates = None

        #: If an siRNA is used in several pools this map will store the data
        #: of which ISO candidate has been used for which one.
        self.__multi_pool_iso_candidates = None

    def reset(self):
        BaseTool.reset(self)
        self.__library_candidates = {}
        self.__md_map = dict()
        self.__picked_candidates = []
        self.__stock_samples = []
        self.__single_pool_map = dict()
        self.__multi_pool_iso_candidates = dict()

    def run(self):
        """
        Runs the optimizer and picks tubes.
        """
        self.reset()
        self.add_info('Start library tube picking optimization ...')

        self.__check_input()
        if not self.has_errors():
            self.__initialize_session()
            self.__create_library_candidates()
            self.__get_single_pools()
        if not self.has_errors():
            self.__get_stock_samples()
        if not self.has_errors():
            self.__run_optimizer()
        if not self.has_errors():
            self.return_value = self.__picked_candidates
            self.add_info('Candidate picking completed.')

    def __initialize_session(self):
        """
        Initializes a session for ORM operations.
        """
        self.__session = Session()

    def __check_input(self):
        """
        Checks the input values.
        """
        self.add_debug('Check input values ...')

        if isinstance(self.molecule_design_pools, (InstrumentedSet, list)):
            for pool in self.molecule_design_pools:
                self._check_input_class('library pool', pool,
                                        MoleculeDesignPool)
            if len(self.molecule_design_pools) < 1:
                msg = 'The pool list is empty!'
                self.add_error(msg)
        else:
            msg = 'The library pool list must be a list or an ' \
                  'InstrumentedSet (obtained: %s).' % \
                  (self.molecule_design_pools.__class__.__name__)
            self.add_error(msg)

        if not is_valid_number(self.stock_concentration):
            msg = 'The stock concentration must be a positive number ' \
                  '(obtained: %s).' % (self.stock_concentration)
            self.add_error(msg)
        if not is_valid_number(self.take_out_volume):
            msg = 'The stock take out volume must be a positive number ' \
                  '(obtained: %s).' % (self.take_out_volume)
            self.add_error(msg)

        if self._check_input_class('excluded racks list',
                                       self.excluded_racks, list):
            for excl_rack in self.excluded_racks:
                if not self._check_input_class('excluded rack barcode',
                                               excl_rack, basestring): break
        if self._check_input_class('requested tubes list',
                                       self.requested_tubes, list):
            for req_tube in self.requested_tubes:
                if not self._check_input_class('requested tube barcode',
                                               req_tube, basestring): break

    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 __get_single_pools(self):
        """
        Determines the single pool (ID) or each requested molecule design.
        """
        self.add_debug('Get single molecule design pool ...')

        md_str = create_in_term_for_db_queries(self.__md_map.keys())
        query_statement = SINGLE_POOL_QUERY.QUERY_TEMPLATE % (md_str)

        results = self.__session.query(*SINGLE_POOL_QUERY.QUERY_RESULTS).\
                                       from_statement(query_statement).all()

        for record in results:
            md_id = record[SINGLE_POOL_QUERY.MOLECULE_DESIGN_INDEX]
            pool_id = record[SINGLE_POOL_QUERY.POOL_INDEX]
            self.__single_pool_map[pool_id] = md_id

        if not len(self.__single_pool_map) == len(self.__md_map):
            missing_ids = []
            for md_id in self.__md_map.keys():
                if not self.__single_pool_map.has_key(md_id):
                    missing_ids.append(md_id)
            msg = 'Could not find single molecule design pool for the ' \
                  'following molecule designs: %s.' % (', '.join(
                            [str(md_id) for md_id in sorted(missing_ids)]))
            self.add_error(msg)

    def __get_stock_samples(self):
        """
        Determines suitable stock samples for the molecule designs required
        to create the pools. Suitable tubes must be managed, have a stock
        concentration and a certain minimum volume.
        """
        self.add_debug('Get stock samples ...')

        conc = self.stock_concentration / CONCENTRATION_CONVERSION_FACTOR
        volume = (self.take_out_volume + STOCK_DEAD_VOLUME) \
                 / VOLUME_CONVERSION_FACTOR
        pool_str = create_in_term_for_db_queries(self.__single_pool_map.keys())

        query_statement = STOCK_SAMPLE_QUERY.QUERY_TEMPLATE % (
                                    pool_str, conc, volume, STOCK_ITEM_STATUS)
        results = self.__session.query(*STOCK_SAMPLE_QUERY.QUERY_RESULTS).\
                  from_statement(query_statement).all()

        found_pools = set()
        for record in results:
            stock_sample_id = record[STOCK_SAMPLE_QUERY.STOCK_SAMPLE_INDEX]
            self.__stock_samples.append(stock_sample_id)
            pool_id = record[STOCK_SAMPLE_QUERY.POOL_INDEX]
            found_pools.add(pool_id)

        if len(found_pools) < 1:
            msg = 'Did not find any suitable stock sample!'
            self.add_error(msg)
        elif not len(found_pools) == len(self.__single_pool_map):
            missing_pools = []
            for pool_id, md_id in self.__single_pool_map.iteritems():
                if not pool_id in found_pools:
                    missing_pools.append('%s (md: %s)' % (pool_id, md_id))
            msg = 'Could not find suitable source stock tubes for the ' \
                  'following molecule design pools: %s.' \
                  % (', '.join(sorted(missing_pools)))
            self.add_warning(msg)

    def __run_optimizer(self):
        """
        Runs the optimizing query and allocates the results to the library
        candidates.
        """
        self.add_debug('Run optimizer ...')

        sample_str = create_in_term_for_db_queries(self.__stock_samples)
        query_statement = LIBRARY_OPTIMIZATION_QUERY.QUERY_TEMPLATE % (
                                                        sample_str, sample_str)

        results = self.__session.query(
                            *LIBRARY_OPTIMIZATION_QUERY.QUERY_RESULT_VALUES).\
                            from_statement(query_statement).all()

        for record in results:
            iso_candidate = IsoCandidate.create_from_query_result(record)
            if iso_candidate.rack_barcode in self.excluded_racks: continue
            self.__store_candidate_data(iso_candidate)

        if len(self.__picked_candidates) < 1:
            msg = 'Did not find any library candidate!'
            self.add_error(msg)

    def __store_candidate_data(self, iso_candidate):
        """
        Adds an ISO candidate to an library candidate and moves the
        library candidate once it is completed.
        """
        single_pool_id = iso_candidate.pool_id
        md_id = self.__single_pool_map[single_pool_id]
        pool_ids = self.__md_map[md_id]
        if len(pool_ids) == 1:
            pool_id = pool_ids[0]
        else:
            for ambi_pool_id in pool_ids:
                pool_id = None
                if not self.__multi_pool_iso_candidates.has_key(ambi_pool_id):
                    self.__multi_pool_iso_candidates[ambi_pool_id] = \
                                        iso_candidate
                    pool_id = ambi_pool_id
                if pool_id is None:
                    pool_id = pool_ids[0]

        libcand = self.__library_candidates[pool_id]
        is_requested = iso_candidate.container_barcode in self.requested_tubes

        if not libcand.has_iso_candidate(md_id):
            libcand.set_iso_candidate(md_id, iso_candidate)
        elif is_requested:
            libcand.replace_candidate(md_id, iso_candidate)

        if libcand.is_completed() and not libcand in self.__picked_candidates:
            self.__picked_candidates.append(libcand)

COMMIT = False
WARNINGS = []

db_server = 'raven'
db_port = '5432'
db_user = '******'
db_password = '******'
db_name = 'unidb'
db_string = "postgresql+psycopg2://%(db_user)s:%(db_password)s" \
            "@%(db_server)s:%(db_port)s/%(db_name)s" % locals()
engine = create_engine(db_string)
metadata = create_metadata(engine)

sess = Session()

sss_query = sess.query(MoleculeDesignPool)

hash_map = {}
total_cnt = sss_query.count()

sss_query = sss_query.options(
                    joinedload(MoleculeDesignPool.stock_samples))

dup_cnt = 1
# Go through all stock sample sets and remove duplicates.
print 'Loading stock sample molecule design sets.'
for cnt, stock_spl_set in enumerate(sss_query.all()):
    sys.stdout.write('Processing %d of %d.' % (cnt + 1, total_cnt))
    if not stock_spl_set.member_hash in hash_map:
示例#3
0
 def __initialize_session(self):
     """
     Initializes a session for ORM operations.
     """
     self.__session = Session()
示例#4
0
import sys

COMMIT = False
WARNINGS = []

db_server = 'raven'
db_port = '5432'
db_user = '******'
db_password = '******'
db_name = 'unidb'
db_string = "postgresql+psycopg2://%(db_user)s:%(db_password)s" \
            "@%(db_server)s:%(db_port)s/%(db_name)s" % locals()
engine = create_engine(db_string)
metadata = create_metadata(engine)

sess = Session()

sss_query = sess.query(MoleculeDesignPool)

hash_map = {}
total_cnt = sss_query.count()

sss_query = sss_query.options(joinedload(MoleculeDesignPool.stock_samples))

dup_cnt = 1
# Go through all stock sample sets and remove duplicates.
print 'Loading stock sample molecule design sets.'
for cnt, stock_spl_set in enumerate(sss_query.all()):
    sys.stdout.write('Processing %d of %d.' % (cnt + 1, total_cnt))
    if not stock_spl_set.member_hash in hash_map:
        hash_map[stock_spl_set.member_hash] = stock_spl_set
示例#5
0
# If this is set to True, the changes will be committed when the script
# completes successfully (i.e., without errors and without warnings).
COMMIT = True

db_server = 'raven'
db_port = '5432'
db_user = '******'
db_password = '******'
db_name = 'buffalo_backup'
db_string = "postgresql+psycopg2://%(db_user)s:%(db_password)s" \
            "@%(db_server)s:%(db_port)s/%(db_name)s" % locals()
engine = create_engine(db_string)
metadata = create_metadata(engine)

sess = Session()

max_row_number = 32
max_col_number = 48

pos_map = dict()

for r in range(max_row_number):

    row_letter = label_from_number(r + 1)
    for c in range(max_col_number):

        label = '%s%i' % (row_letter, c + 1)
        rack_pos = RackPosition(row_index=r, column_index=c, label=label)
        pos_map[label] = rack_pos
        sess.add(rack_pos)
# If this is set to True, the changes will be committed when the script
# completes successfully (i.e., without errors and without warnings).
COMMIT = True

db_server = 'raven'
db_port = '5432'
db_user = '******'
db_password = '******'
db_name = 'buffalo_backup'
db_string = "postgresql+psycopg2://%(db_user)s:%(db_password)s" \
            "@%(db_server)s:%(db_port)s/%(db_name)s" % locals()
engine = create_engine(db_string)
metadata = create_metadata(engine)

sess = Session()

max_row_number = 32
max_col_number = 48

pos_map = dict()

for r in range(max_row_number):

    row_letter = label_from_number(r + 1)
    for c in range(max_col_number):

        label = '%s%i' % (row_letter, c + 1)
        rack_pos = RackPosition(row_index=r, column_index=c, label=label)
        pos_map[label] = rack_pos
        sess.add(rack_pos)
示例#7
0
 def tear_down(self):
     super(RdbTestCaseMixin, self).tear_down()
     Session.remove()
示例#8
0
# If this is set to True, the changes will be committed when the script
# completes successfully (i.e., without errors and without warnings).
COMMIT = False

db_server = 'raven'
db_port = '5432'
db_user = '******'
db_password = '******'
db_name = 'unidb'
db_string = "postgresql+psycopg2://%(db_user)s:%(db_password)s" \
            "@%(db_server)s:%(db_port)s/%(db_name)s" % locals()
engine = create_engine(db_string)
metadata = create_metadata(engine)

sess = Session()


def process_or_create_structure(molecule_design, structure_type,
                                representation, new_structures):
    cs_query = sess.query(ChemicalStructure)
    md5_rpr = md5(representation).hexdigest()
    try:
        cs = cs_query.filter(
                func.md5(ChemicalStructure.representation) == md5_rpr,
                ChemicalStructure.structure_type == structure_type).one()
    except NoResultFound:
        cs = None
    if cs is None:
        if structure_type == CHEMICAL_STRUCTURE_TYPE_IDS.COMPOUND:
            structure_class = CompoundChemicalStructure