Example #1
0
 def __init__(self, exp=None):
     print('bobo')
     super().__init__(database_name='dbBact',
                      methods=['get', 'annotate', 'enrichment'])
     username = get_config_value('username', section='dbbact')
     password = get_config_value('password', section='dbbact')
     self.db = DBAccess(username=username, password=password)
Example #2
0
    def __init__(self, exp=None):
        super().__init__(database_name='SpongeWorld', methods=['get'])

        # Web address of the bact server
        self.dburl = self._get_db_address()
        self.username = get_config_value('username', section='dbBact')
        self.password = get_config_value('password', section='dbBact')
        self.web_interface = self.dburl
Example #3
0
 def test_config_file_value(self):
     # test the set and get config file values
     # create the tmp config file path
     d = mkdtemp()
     f = join(d, 'config.txt')
     util.set_config_value('test1', 'val1', config_file_name=f)
     res = util.get_config_value('test1', config_file_name=f)
     self.assertEqual(res, 'val1')
     # test the fallback if a key doesn't exist
     res = util.get_config_value('test2', fallback='na', config_file_name=f)
     self.assertEqual(res, 'na')
     shutil.rmtree(d)
Example #4
0
def show_and_ask(msg, keyval):
    keyval = 'skip_msg_' + keyval
    res = get_config_value(keyval, section='dbbact', fallback='no')
    if res.lower() == 'yes':
        return
    a = QtWidgets.QMessageBox()
    a.setText(msg)
    a.setWindowTitle('dbBact-Calour')
    a.setIcon(QtWidgets.QMessageBox.Information)
    a.setStandardButtons(QtWidgets.QMessageBox.Ok)
    cb = QtWidgets.QCheckBox(text="Don't show this again")
    a.setCheckBox(cb)
    a.exec_()
    if cb.isChecked():
        set_config_value(keyval, 'yes', section='dbbact')
def show_enriched_terms_qt5(cdb,
                            group1,
                            group2=None,
                            exp=None,
                            max_id=None,
                            group1_name=None,
                            group2_name=None,
                            **kwargs):
    '''Show enriched terms between group1 and group2 using a qt5 GUI

    The gui shows a list of terms enriched in the 2 groups, and enables plotting per term heatmap and venn diagram.

    Parameters
    ----------
    cdb: DBBact.DBAccess
        the database interface for the analysis
    group1: list of str ('ACGT')
        the first group of sequences
    group2: list of str or None, optional
        the second group of sequences
        if None, group2 is taken from exp by using all sequences not in group1
    exp: calour.Experiment or None, optional
        the experiment on which the analysis is performed.
        If not None, annotations are taken from the experiment (if available)
        NOTE: if annotations are not available, they will be added to the experiment the first time the function is called
        If None, annotations are always queried from dbbact from each group and not stored for further queries.
    max_id: int or None, optional
        if not None, limit results to annotation ids <= max_id
    **kwargs: additional parameters supplied to db_access.term_enrichment(). These include:
    term_type : str or None (optional)
        The type of annotation data to test for enrichment
        options are:
        'term' - ontology terms associated with each feature.
        'parentterm' - ontology terms including parent terms associated with each feature.
        'annotation' - the full annotation strings associated with each feature
        'combined' - combine 'term' and 'annotation'
    ignore_exp: list of int or None or True, optional
        List of experiments to ignore in the analysis
        True to ignore annotations from the current experiment
        None (default) to use annotations from all experiments including the current one
    min_appearances : int (optional)
        The minimal number of times a term appears in order to include in output list.
    fdr_method : str (optional)
        The FDR method used for detecting enriched terms (permutation test). options are:
        'dsfdr' (default): use the discrete FDR correction
        'bhfdr': use Benjamini Hochbert FDR correction
    score_method : str (optional)
        The score method used for calculating the term score. Options are:
        'all_mean' (default): mean over each experiment of all annotations containing the term
        'sum' : sum of all annotations (experiment not taken into account)
        'card_mean': use a null model keeping the number of annotations per each bacteria
    random_seed: int or None
        int to specify the random seed for numpy.random.
    use_term_pairs: bool, optional
        True to also test enrichment in pairs of terms (i.e. h**o sapiens+feces, etc.)
    focus_terms: list of str or None, optional
        if not None, use only annotations containing all the terms in focus_terms
    '''
    if group1_name is None:
        group1_name = 'Group1'
    if exp is None:
        logger.debug('No experiment supplied - getting annotations')
        # need to write
        all_features = set(group1).union(set(group2))
        # get all the annotations....
        # all_annotations = exp.exp_metadata['__dbbact_annotations']
        # seq_annotations = exp.exp_metadata['__dbbact_sequence_annotations']
        # term_info = exp.exp_metadata.get('__dbbact_term_info')
        raise ValueError('exp=None not supported yet.')
    else:
        # add all annotations to experiment if not already added
        cdb.add_all_annotations_to_exp(exp, max_id=max_id, force=False)
        all_annotations = exp.databases['dbbact']['annotations']
        seq_annotations = exp.databases['dbbact']['sequence_annotations']
        term_info = exp.databases['dbbact'].get('term_info')

        # prepare group2 by taking all features from exp that are not in group1
        if group2 is None:
            logger.debug('Using experiment sequences for group2')
            exp_features = set(exp.feature_metadata.index.values)
            group2 = np.array(list(exp_features.difference(group1)))
            if group2_name is None:
                group2_name = 'NOT %s' % group1_name

        if group2_name is None:
            group2_name = 'Group2'

        # validate all features are in exp. otherwise ignore them
        exp_features = set(exp.feature_metadata.index.values)
        all_features = set(group1).union(set(group2))
        bad_features = all_features.difference(exp_features)
        if len(bad_features) > 0:
            logger.warning(
                'Some of the features for enrichment are not in the experiment. Ignoring %d features'
                % len(bad_features))
            group1 = list(set(group1).intersection(exp_features))
            group2 = list(set(group2).intersection(exp_features))
            if len(group1) == 0:
                raise ValueError(
                    "No features left in group1 after ignoring. Please make sure you test for enrichment with features from the experiment."
                )
            if len(group2) == 0:
                raise ValueError(
                    "No features left in group2 after ignoring. Please make sure you test for enrichment with features from the experiment."
                )

    # if ignore exp is True, it means we should ignore the current experiment
    ignore_exp = kwargs.get('ignore_exp')
    if ignore_exp is True:
        ignore_exp = cdb.db.find_experiment_id(
            datamd5=exp.info['data_md5'],
            mapmd5=exp.info['sample_metadata_md5'],
            getall=True)
        if ignore_exp is None:
            logger.warn(
                'No matching experiment found in dbBact. Not ignoring any experiments'
            )
        else:
            logger.info(
                'Found %d experiments (%s) matching current experiment - ignoring them.'
                % (len(ignore_exp), ignore_exp))
    kwargs['ignore_exp'] = ignore_exp

    method = 'meandiff'
    transform_type = 'rankdata'
    # we only show the enrichment method dialog if it is specified in the config file
    # since the enrichment method is for advanced users...
    show_enrich_method_dialog = get_config_value('show_enrich_method_dialog',
                                                 section='dbbact')
    if show_enrich_method_dialog is not None:
        if show_enrich_method_dialog.lower() == 'yes':
            # Ask user whether to do card_enrichment (normalize number of annotations per sequence - used for background enrichment) or diff_enrichment (used for differential abundance results)
            a = QtWidgets.QMessageBox()
            a.setText(
                'Select dbBact term enrichment method:\nCard for background comparison enrichment\nDiff for two group (diff. abundance result) enrichment'
            )
            a.setWindowTitle('Term enrichment method')
            a.setIcon(QtWidgets.QMessageBox.Question)
            a.addButton("Card", QtWidgets.QMessageBox.YesRole)
            a.addButton("Diff", QtWidgets.QMessageBox.NoRole)
            a.addButton("Cancel", QtWidgets.QMessageBox.RejectRole)
            res = a.exec_()
            # cancel
            if (res == 2):
                logger.debug('cancel enrichment analysis')
                return
            # diff
            if (res == 1):
                method = 'meandiff'
                transform_type = 'rankdata'
                logger.info('Using differential term enrichment method')
            # card
            if (res == 0):
                method = 'card_mean'
                transform_type = None
                logger.info('Using card (BG) term enrichment method')

    logger.debug('using enrichment method: %s, transform: %s' %
                 (method, transform_type))

    # get the enriched terms (pandas dataframe)
    enriched, resmat, features = cdb.db.term_enrichment(
        g1_features=group1,
        g2_features=group2,
        all_annotations=all_annotations,
        seq_annotations=seq_annotations,
        term_info=term_info,
        method=method,
        transform_type=transform_type,
        **kwargs)
    logger.debug('Got %d enriched terms' % len(enriched))

    app, app_created = init_qt5()

    if len(enriched) == 0:
        QtWidgets.QMessageBox.information(
            None, "No enriched terms found",
            "No enriched annotations found when comparing\n%d selected sequences to %d "
            "other sequences" % (len(group1), len(group2)))
        return

    # sort by absolute value of effect size, so terms appear from high to low in both lists
    enriched['odif_abs'] = enriched['odif'].abs()
    enriched = enriched.sort_values('odif_abs', ascending=False)

    # add the terms to the appropriate list
    listwin = TermInfoListWindow(listname='enriched ontology terms',
                                 group1name=group1_name,
                                 group2name=group2_name)
    for idx, cres in enriched.iterrows():
        if cres['odif'] > 0:
            ccolor = 'blue'
            cgroup = 1
        else:
            ccolor = 'red'
            cgroup = 2
        cname = cres['term']
        # For each enriched term, double clicking will display a heatmap
        # where all annotations containing the term are the features,
        # and bacteria (from the two compared groups) are the samples.
        # This enables seeing where does the enrichment for this term come from.
        # i.e. which bacteria are present in each annotation containing this term.
        dblclick_data = {}
        dblclick_data['database'] = cdb
        dblclick_data['term'] = cname
        dblclick_data['exp'] = exp
        g1_seqs = set(group1)
        g2_seqs = set(group2)
        ordered_g1_seqs = [
            s for s in exp.feature_metadata.index.values[::-1] if s in g1_seqs
        ]
        ordered_g2_seqs = [
            s for s in exp.feature_metadata.index.values[::-1] if s in g2_seqs
        ]
        dblclick_data['features1'] = ordered_g1_seqs
        dblclick_data['features2'] = ordered_g2_seqs
        listwin.add_item('%s - effect %f, pval %f ' %
                         (cname, cres['odif'], cres['pvals']),
                         color=ccolor,
                         dblclick_data=dblclick_data,
                         group=cgroup)

    listwin.exec_()
Example #6
0
def test_user_password(db):
    '''
    Test if the config file has user/password and if not ask for one.
    Also don't ask if the 'ask again' checkbox is checked

    Parameters
    ----------
    db : DBBact.DBAccess
        the database interface class.
    '''
    logger.debug('Testing if user/pwd in config file')
    username = get_config_value('username', section='dbbact')
    if username is not None:
        logger.debug('found user %s' % username)
        return
    if get_config_value('show_user_request', section='dbbact') is not None:
        logger.debug(
            'user/password not set, but show_user_request flag in config file is set, so ignoring'
        )
        return
    logger.debug('no username in config file')
    if QtWidgets.QMessageBox.warning(
            None, 'Register/login for better annotation',
            'You can add annotations as an anonymous user, '
            'or register/login in order to create non-anonymous annotations.\n'
            'NOTE: annonymous annotations can be modified/deleted by any user, '
            'whereas non-annonymous annotations can be modified/deleted only by the user who created them.\n\n'
            'Click "Yes" to register/login or "No" to continue as annonymous user',
            QtWidgets.QMessageBox.Yes,
            QtWidgets.QMessageBox.No) == QtWidgets.QMessageBox.No:
        return
    ui = UserPasswordDlg()
    res = ui.exec_()
    if res == QtWidgets.QDialog.Accepted:
        username = str(ui.username.text())
        password = str(ui.password.text())
        db.username = username
        db.password = password
        userid = db.get_user_id()
        if userid is None:
            logger.debug('userid/password not found. Registering')
            email = str(ui.email.text())
            description = str(ui.interest.currentText())
            err = db.register_user(username,
                                   password,
                                   email=email,
                                   description=description,
                                   publish='n',
                                   name='')
            if err:
                logger.warn(err)
                QtWidgets.QMessageBox.warning(
                    None, 'Login failed', 'login for user %s failed.\n'
                    'You are now logged in as anonymous user.' % username)
                return
            QtWidgets.QMessageBox.information(
                None, 'Registered new user',
                'New user %s registered in dbBact.\n'
                'You can change the Calour dbBact user/password in the config file:\n'
                '%s' % (username, get_config_file()))
        else:
            userid = db.get_user_id()
            if userid is not None:
                QtWidgets.QMessageBox.information(
                    None, 'Logged in existing user',
                    'user %s logged into dbBact.\n'
                    'You can change the Calour dbBact user/password in the config file:\n'
                    '%s' % (username, get_config_file()))
            else:
                QtWidgets.QMessageBox.warning(
                    None, 'Login failed', 'login for user %s failed.\n'
                    'You are now logged in as anonymous user.' % username)
                return

        logger.info('storing username %s in config file' % username)
        set_config_value('username', username, section='dbbact')
        set_config_value('password', password, section='dbbact')