In [1]:
import sys
import os
sys.path.append(os.path.abspath("/users/amtseng/tfmodisco/src/"))
import numpy as np
import h5py
import matplotlib.pyplot as plt
import motif.read_motifs as read_motifs
import motif.match_motifs as match_motifs
from util import figure_to_vdom_image
import plot.viz_sequence as viz_sequence
import vdom.helpers as vdomh
from IPython.display import display
Exception in thread Thread-3:
Traceback (most recent call last):
  File "/users/amtseng/miniconda3/envs/tfmodisco-mini/lib/python3.7/threading.py", line 926, in _bootstrap_inner
    self.run()
  File "/users/amtseng/miniconda3/envs/tfmodisco-mini/lib/python3.7/site-packages/ipykernel/heartbeat.py", line 93, in run
    self._bind_socket()
  File "/users/amtseng/miniconda3/envs/tfmodisco-mini/lib/python3.7/site-packages/ipykernel/heartbeat.py", line 74, in _bind_socket
    self._try_bind_socket()
  File "/users/amtseng/miniconda3/envs/tfmodisco-mini/lib/python3.7/site-packages/ipykernel/heartbeat.py", line 61, in _try_bind_socket
    return self.socket.bind('%s://%s' % (self.transport, self.ip) + c + str(self.port))
  File "zmq/backend/cython/socket.pyx", line 550, in zmq.backend.cython.socket.Socket.bind
  File "zmq/backend/cython/checkrc.pxd", line 26, in zmq.backend.cython.checkrc._check_rc
zmq.error.ZMQError: Address already in use

In [2]:
# Define parameters/fetch arguments
tf_name = os.environ["TFM_TF_NAME"]
multitask_fold = int(os.environ["TFM_MULTITASK_FOLD"])
head = os.environ["TFM_HEAD"]
assert head in ("profile", "count")
if "TFM_TASK_INDEX" in os.environ:
    task_index = int(os.environ["TFM_TASK_INDEX"])
    singletask_fold = int(os.environ["TFM_SINGLETASK_FOLD"])
else:
    task_index = None
    singletask_fold = None
motif_file = os.environ["TFM_MOTIF_FILE"]  # TF-MoDISco motifs
    
print("TF name: %s" % tf_name)
print("Multi-task fold: %s" % multitask_fold)
print("Head: %s" % head)
print("Task index: %s" % task_index)
print("Single-task fold: %s" % singletask_fold)
print("TF-MoDISco motif file: %s" % motif_file)
TF name: REST
Multi-task fold: 7
Head: profile
Task index: 3
Single-task fold: 2
TF-MoDISco motif file: /users/amtseng/tfmodisco/results/reports/tfmodisco_results/cache/multitask_profile_finetune/REST_multitask_profile_finetune_fold7/REST_multitask_profile_finetune_task3_fold7_profile/all_motifs.h5
In [3]:
# Define paths and constants
base_path = "/users/amtseng/tfmodisco/results/classic_motifs/"

multitask_seqlets_dir = os.path.join(
    base_path, "seqlets", "multitask_profile_finetune",
    "%s_multitask_profile_finetune_fold%s" % (tf_name, multitask_fold)
)

if task_index is None:
    peaks_path = os.path.join(base_path, "peaks", tf_name, "%s_peaks_taskall" % tf_name)
    multitask_seqlets_path = os.path.join(
        multitask_seqlets_dir,
        "%s_seqlets_%s_taskall" % (tf_name, head)
    )
else:
    peaks_path = os.path.join(base_path, "peaks", tf_name, "%s_peaks_task%d" % (tf_name, task_index))
    multitask_seqlets_path = os.path.join(
        multitask_seqlets_dir,
        "%s_seqlets_%s_task%d" % (tf_name, head, task_index)
    )
    
    singletask_seqlets_dir = os.path.join(
        base_path, "seqlets", "singletask_profile_finetune",
        "%s_singletask_profile_finetune_fold%s" % (tf_name, singletask_fold),
        "task_%d" % task_index
    )
    singletask_seqlets_path = os.path.join(
        singletask_seqlets_dir,
        "%s_seqlets_%s_task%d" % (tf_name, head, task_index)
    )

Helper functions

In [4]:
def import_tfmodisco_motifs(motif_file):
    """
    Imports a set of motifs from the saved HDF5.
    Returns a list of motifs as L x 4 arrays, and a parallel list of
    motif names.
    """
    motifs, motif_names = [], []
    with h5py.File(motif_file, "r") as f:
        for key in f.keys():
            motif_names.append(key)
            motifs.append(f[key]["pfm_trimmed"][:])
    return motifs, motif_names
In [5]:
def pfm_to_forward_pwm(pfm):
    """
    Converts PFM to PWM and flips to purine-rich orientation.
    """
    pwm = read_motifs.pfm_to_pwm(pfm)
    if np.sum(pwm[:, [0, 2]]) < 0.5 * np.sum(pwm):
        # Flip to purine-rich version
        pwm = np.flip(pwm, axis=(0, 1))
    return pwm
In [6]:
def show_matched_motifs_table(
    tfm_motifs, tfm_names, bench_type, bench_motifs, bench_scores, matches
):
    """
    Shows a table of motifs from the given matched results.
    `bench_type` is either `dichipmunk`, `homer`, or `meme`.
    `matches` is NumPy array parallel to `bench_motifs`, where
    each entry is the index of the match in `tfm_motifs`, and -1
    if no match was found.
    """
    assert len(matches) == len(bench_motifs)
    assert bench_type in ("dichipmunk", "homer", "meme")
    if bench_type == "dichipmunk":
        score_name = "Supporting sequences"
        bench_name = "DiChIPMunk"
    elif bench_type == "homer":
        score_name = "Log enrichment"
        bench_name = "HOMER"
    else:
        score_name = "E-value"
        bench_name = "MEME"
        
    colgroup = vdomh.colgroup(
        vdomh.col(style={"width": "5%"}),
        vdomh.col(style={"width": "45%"}),
        vdomh.col(style={"width": "5%"}),
        vdomh.col(style={"width": "45%"})
    )
    header = vdomh.thead(
        vdomh.tr(
            vdomh.th("TF-MoDISco motif ID", style={"text-align": "center"}),
            vdomh.th("TF-MoDISco PWM", style={"text-align": "center"}),
            vdomh.th(score_name, style={"text-align": "center"}),
            vdomh.th("%s PWM" % bench_name, style={"text-align": "center"})
        )
    )
    
    # First, show a table of matches
    display(vdomh.p("Matched motifs"))

    body = []
    for bench_index, tfm_index in enumerate(matches):
        if tfm_index == -1:
            continue
        tfm_fig = viz_sequence.plot_weights(
            pfm_to_forward_pwm(tfm_motifs[tfm_index]), figsize=(20, 4), return_fig=True
        )
        tfm_fig.tight_layout()
        bench_fig = viz_sequence.plot_weights(
            pfm_to_forward_pwm(bench_motifs[bench_index]), figsize=(20, 4), return_fig=True
        )
        bench_fig.tight_layout()
        
        body.append(
            vdomh.tr(
                vdomh.td(str(tfm_names[tfm_index])),
                vdomh.td(figure_to_vdom_image(tfm_fig)),
                vdomh.td(str(bench_scores[bench_index])),
                vdomh.td(figure_to_vdom_image(bench_fig))
            )
        )

    display(vdomh.table(colgroup, header, vdomh.tbody(*body)))
    plt.close("all")
    
    # Now, show a table of leftovers
    display(vdomh.p("Motifs without matches"))
    
    tfm_lone_indices = np.setdiff1d(np.arange(len(tfm_motifs)), matches)
    bench_lone_indices = np.where(matches == -1)[0]

    rows = []
    for i in range(max(len(tfm_lone_indices), len(bench_lone_indices))):
        row = []
        if i < len(tfm_lone_indices):
            tfm_fig = viz_sequence.plot_weights(
                pfm_to_forward_pwm(tfm_motifs[tfm_lone_indices[i]]), figsize=(20, 4), return_fig=True
            )
            tfm_fig.tight_layout()
            row.extend([
                vdomh.td(str(tfm_names[tfm_lone_indices[i]])),
                vdomh.td(figure_to_vdom_image(tfm_fig))
            ])
        else:
            row.extend([vdomh.td(), vdomh.td()])
        if i < len(bench_lone_indices):
            bench_fig = viz_sequence.plot_weights(
                pfm_to_forward_pwm(bench_motifs[bench_lone_indices[i]]), figsize=(20, 4), return_fig=True
            )
            bench_fig.tight_layout()
            row.extend([
                vdomh.td(str(bench_scores[bench_lone_indices[i]])),
                vdomh.td(figure_to_vdom_image(bench_fig))
            ])
        else:
            row.extend([vdomh.td(), vdomh.td()])
        rows.append(row)
    body = [vdomh.tr(*row) for row in rows]

    display(vdomh.table(colgroup, header, vdomh.tbody(*body)))
    plt.close("all")

Import motifs

In [7]:
tfm_pfms, tfm_names = import_tfmodisco_motifs(motif_file)
In [8]:
dichipmunk_peak_pfms, dichipmunk_peak_num_seqs = read_motifs.import_dichipmunk_pfms(
    os.path.join(peaks_path, "dichipmunk")
)
dichipmunk_multitask_seqlet_pfms, dichipmunk_multitask_seqlet_num_seqs = read_motifs.import_dichipmunk_pfms(
    os.path.join(multitask_seqlets_path, "dichipmunk")
)

homer_peak_pfms, homer_peak_enrichments = read_motifs.import_homer_pfms(
    os.path.join(peaks_path, "homer")
)
homer_multitask_seqlet_pfms, homer_multitask_seqlet_enrichments = read_motifs.import_homer_pfms(
    os.path.join(multitask_seqlets_path, "homer")
)

meme_peak_pfms, meme_peak_evalues = read_motifs.import_meme_pfms(
    os.path.join(peaks_path, "meme")
)
meme_multitask_seqlet_pfms, meme_multitask_seqlet_evalues = read_motifs.import_meme_pfms(
    os.path.join(multitask_seqlets_path, "meme")
)

if task_index is not None:
    dichipmunk_singletask_seqlet_pfms, dichipmunk_singletask_seqlet_num_seqs = read_motifs.import_dichipmunk_pfms(
        os.path.join(singletask_seqlets_path, "dichipmunk")
    )
    homer_singletask_seqlet_pfms, homer_singletask_seqlet_enrichments = read_motifs.import_homer_pfms(
        os.path.join(singletask_seqlets_path, "homer")
    )
    meme_singletask_seqlet_pfms, meme_singletask_seqlet_evalues = read_motifs.import_meme_pfms(
        os.path.join(singletask_seqlets_path, "meme")
    )

Match benchmarked motifs to TF-MoDISco motifs

DiChIPMunk on peaks

In [9]:
dichipmunk_peak_matches = match_motifs.match_motifs_to_targets(dichipmunk_peak_pfms, tfm_pfms)
show_matched_motifs_table(
    tfm_pfms, tfm_names, "dichipmunk", dichipmunk_peak_pfms, dichipmunk_peak_num_seqs,
    dichipmunk_peak_matches
)

Matched motifs

TF-MoDISco motif IDTF-MoDISco PWMSupporting sequencesDiChIPMunk PWM
0_0
815
0_8
108
0_5
35
0_1
10
0_9
1

Motifs without matches

TF-MoDISco motif IDTF-MoDISco PWMSupporting sequencesDiChIPMunk PWM
0_10
1
0_11
0_2
0_3
0_4
0_6
0_7

DiChIPMunk on multi-task seqlets

In [10]:
dichipmunk_multitask_seqlet_matches = match_motifs.match_motifs_to_targets(dichipmunk_multitask_seqlet_pfms, tfm_pfms)
show_matched_motifs_table(
    tfm_pfms, tfm_names, "dichipmunk", dichipmunk_multitask_seqlet_pfms, dichipmunk_multitask_seqlet_num_seqs,
    dichipmunk_multitask_seqlet_matches
)

Matched motifs

TF-MoDISco motif IDTF-MoDISco PWMSupporting sequencesDiChIPMunk PWM
0_0
5315
0_2
1195

Motifs without matches

TF-MoDISco motif IDTF-MoDISco PWMSupporting sequencesDiChIPMunk PWM
0_1
0_10
0_11
0_3
0_4
0_5
0_6
0_7
0_8
0_9

DiChIPMunk on single-task seqlets

In [11]:
if task_index is not None:
    dichipmunk_singletask_seqlet_matches = match_motifs.match_motifs_to_targets(dichipmunk_singletask_seqlet_pfms, tfm_pfms)
    show_matched_motifs_table(
        tfm_pfms, tfm_names, "dichipmunk", dichipmunk_singletask_seqlet_pfms, dichipmunk_singletask_seqlet_num_seqs,
        dichipmunk_singletask_seqlet_matches
    )

Matched motifs

TF-MoDISco motif IDTF-MoDISco PWMSupporting sequencesDiChIPMunk PWM
0_0
5180
0_7
147
0_9
33

Motifs without matches

TF-MoDISco motif IDTF-MoDISco PWMSupporting sequencesDiChIPMunk PWM
0_1
617
0_10
0_11
0_2
0_3
0_4
0_5
0_6
0_8

HOMER on peaks

In [12]:
homer_peak_matches = match_motifs.match_motifs_to_targets(homer_peak_pfms, tfm_pfms)
show_matched_motifs_table(
    tfm_pfms, tfm_names, "homer", homer_peak_pfms, homer_peak_enrichments,
    homer_peak_matches
)

Matched motifs

/users/amtseng/tfmodisco/src/plot/viz_sequence.py:152: RuntimeWarning: More than 20 figures have been opened. Figures created through the pyplot interface (`matplotlib.pyplot.figure`) are retained until explicitly closed and may consume too much memory. (To control this warning, see the rcParam `figure.max_open_warning`).
  fig = plt.figure(figsize=figsize)
TF-MoDISco motif IDTF-MoDISco PWMLog enrichmentHOMER PWM
0_4
-3726.436413
0_0
-3513.750529
0_11
-300.395464
0_3
-220.700355
0_9
-164.589326
0_10
-101.975318
0_0
-94.495886
0_8
-94.263783
0_6
-77.510539
0_9
-55.606894
0_10
-42.619072

Motifs without matches

TF-MoDISco motif IDTF-MoDISco PWMLog enrichmentHOMER PWM
0_1
-130.035534
0_2
-103.04714
0_5
-69.75864
0_7
-39.119266

HOMER on multi-task seqlets

In [13]:
homer_multitask_seqlet_matches = match_motifs.match_motifs_to_targets(homer_multitask_seqlet_pfms, tfm_pfms)
show_matched_motifs_table(
    tfm_pfms, tfm_names, "homer", homer_multitask_seqlet_pfms, homer_multitask_seqlet_enrichments,
    homer_multitask_seqlet_matches
)

Matched motifs

TF-MoDISco motif IDTF-MoDISco PWMLog enrichmentHOMER PWM
0_0
-8848.602276
0_0
-6008.149467
0_1
-1757.528312
0_7
-839.261127
0_6
-265.294695
0_9
-88.376105
0_10
-63.076107
0_6
-51.95242

Motifs without matches

TF-MoDISco motif IDTF-MoDISco PWMLog enrichmentHOMER PWM
0_11
-35.411621
0_2
-11.338435
0_3
0_4
0_5
0_8

HOMER on single-task seqlets

In [14]:
if task_index is not None:
    homer_singletask_seqlet_matches = match_motifs.match_motifs_to_targets(homer_singletask_seqlet_pfms, tfm_pfms)
    show_matched_motifs_table(
        tfm_pfms, tfm_names, "homer", homer_singletask_seqlet_pfms, homer_singletask_seqlet_enrichments,
        homer_singletask_seqlet_matches
    )

Matched motifs

TF-MoDISco motif IDTF-MoDISco PWMLog enrichmentHOMER PWM
0_0
-8956.006352
0_7
-8258.344409
0_4
-4224.931199
0_9
-97.06283
0_9
-94.056688
0_10
-15.56351

Motifs without matches

TF-MoDISco motif IDTF-MoDISco PWMLog enrichmentHOMER PWM
0_1
-116.373247
0_11
-99.968189
0_2
-51.759438
0_3
0_5
0_6
0_8

MEME on peaks

In [15]:
meme_peak_matches = match_motifs.match_motifs_to_targets(meme_peak_pfms, tfm_pfms)
show_matched_motifs_table(
    tfm_pfms, tfm_names, "meme", meme_peak_pfms, meme_peak_evalues,
    meme_peak_matches
)

Matched motifs

TF-MoDISco motif IDTF-MoDISco PWME-valueMEME PWM
0_0
7.4e-1770
0_8
3.7e-106
0_10
1.6e-060
0_4
6.3e-057
0_6
1.5e-029
0_10
8.6e-008
0_10
6.6e-002
0_6
1.0e+002
0_9
5.6e+003

Motifs without matches

TF-MoDISco motif IDTF-MoDISco PWME-valueMEME PWM
0_1
9.2e-004
0_11
0_2
0_3
0_5
0_7

MEME on multi-task seqlets

In [16]:
meme_multitask_seqlet_matches = match_motifs.match_motifs_to_targets(meme_multitask_seqlet_pfms, tfm_pfms)
show_matched_motifs_table(
    tfm_pfms, tfm_names, "meme", meme_multitask_seqlet_pfms, meme_multitask_seqlet_evalues,
    meme_multitask_seqlet_matches
)

Matched motifs

TF-MoDISco motif IDTF-MoDISco PWME-valueMEME PWM
0_1
3.6e-454
0_4
1.6e-388
0_10
1.2e-024
0_3
2.8e-007
0_6
7.8e-001
0_0
1.6e+002
0_7
6.8e+004

Motifs without matches

TF-MoDISco motif IDTF-MoDISco PWME-valueMEME PWM
0_11
1.7e+003
0_2
5.0e+003
0_5
5.7e+003
0_8
0_9

MEME on single-task seqlets

In [17]:
if task_index is not None:
    meme_singletask_seqlet_matches = match_motifs.match_motifs_to_targets(meme_singletask_seqlet_pfms, tfm_pfms)
    show_matched_motifs_table(
        tfm_pfms, tfm_names, "meme", meme_singletask_seqlet_pfms, meme_singletask_seqlet_evalues,
        meme_singletask_seqlet_matches
    )

Matched motifs

TF-MoDISco motif IDTF-MoDISco PWME-valueMEME PWM
0_0
7.4e-753
0_1
3.1e-294
0_4
3.9e-037
0_10
1.1e-011
0_9
9.2e+001
0_4
1.1e+005

Motifs without matches

TF-MoDISco motif IDTF-MoDISco PWME-valueMEME PWM
0_11
8.4e+003
0_2
4.6e+005
0_3
6.3e+005
0_5
8.2e+005
0_6
0_7
0_8