<jupyter_start><jupyter_text>Quantify mCG at the enhancers<jupyter_code>import sys, os
sys.path.insert(0, '/cndd/fangming/CEMBA/snmcseq_dev')
from __init__ import *
from CEMBA_run_mc_region_level import run_mc_region_level 
from natsort import natsorted
import glob , re
# bed_file='enhancers_reptile.bed'
# allc_dir='/cndd2/fangming/scf_enhancers/data/bulk/round2/mc/'
# allc_files=glob.glob(allc_dir+'Round2*CGN-Merge.allc.tsv.gz')

# # bed_file='foo.bed'
# # allc_files = [allc_files[0]]

# output_files = ['enh.'+os.path.split(a)[1][:-22]+'.bed.gz' for a in allc_files]
# cap = 0 # no counts cap
# nprocs = 8
# compress = True
# bed_file_name_column = False
# chr_prefix = True
# contexts = ['CG']

# run_mc_region_level(allc_files, 
#                     output_files, 
#                     bed_file, 
#                     chr_prefix=chr_prefix,
#                     bed_file_name_column=bed_file_name_column,
#                     contexts=contexts,
#                     compress=compress, 
#                     cap=cap,
#                     nprocs=nprocs);
# # Gather data from all the individual bed files
# df = pd.DataFrame();
# for fn in output_files:
    
#     _, sample = os.path.split(fn)
#     sample = re.sub('(enh\.|\.bed)','',sample)

#     x = pd.read_csv(fn+'.gz',sep='\t')
#     x=x.rename(mapper={'mCG': sample+'_'+'mCG', 'CG': sample+'_'+'CG'}, axis=1)
#     if df.shape[0]<1:
#         df = x
#     else:
#         df = df.join(x.iloc[:,[3,4]])
        
# df['enh_pos'] = 'chr'+df['chr'].astype(str)+'_'+df['start'].astype(str)+'_'+df['end'].astype(str)
# df.to_csv('enh.AllClusters.mCG.bed.gz')
# for fn in output_files:
#     os.remove(fn)
#     print('Removed file %s' % fn)<jupyter_output><empty_output><jupyter_text>Load enhancer data<jupyter_code># Map the genes to closest enhancers
datadir = '/cndd/emukamel/enhancer_modeling/enhancer_data/'
genes2enh = pd.read_csv(datadir+'genes.gencode.vM16.closest_enhancers.bed',sep='\t',
                        names = ['gene_chr','gene_start','gene_end','ensid','gene_name','enh_chr','enh_start','enh_end'])
genes2enh['enh_pos'] = genes2enh['enh_chr']+'_'+genes2enh['enh_start'].astype(str)+'_'+genes2enh['enh_end'].astype(str)
genes2enh.ensid = [re.sub("\..*","",x) for x in genes2enh.ensid]
genes2enh = genes2enh.set_index('ensid')
genes = pd.read_csv(datadir+'genes.gencode.vM16.bed',sep='\t',header=None,
                   names=['chr','start','end','ensid','gene'])
genes['ensid'] = [re.sub('\..*','',ensid) for ensid in genes['ensid']]
genes = genes.set_index('ensid',drop=False)
genes<jupyter_output><empty_output><jupyter_text>Load RNA data<jupyter_code>datadir='/cndd2/ethan/projects/scf_paper/modeling/working_data/reptile/data_for_model_01152020/'
rna = pd.read_csv(datadir+'rna_for_y_values.tsv',sep='\t')
rcol = rna.columns.values
rcol[1] = 'ensid'
rna.columns = rcol
# rna=rna.drop('10-1',axis=1)
# rna_data = rna.iloc[:,2:].to_numpy()

# Variable genes
hvg = np.var(rna.iloc[:,2:].to_numpy(),axis=1);
hvg = hvg> np.percentile(hvg,67)
np.sum(hvg)

rna = rna[hvg]
rna = rna.set_index('ensid')
rna<jupyter_output><empty_output><jupyter_text>Load mCG data<jupyter_code>datadir = '/cndd/emukamel/enhancer_modeling/enhancer_data/'
df = pd.read_csv(datadir+'enh.AllClusters.mCG.bed.gz')
df['enh_pos'] = 'chr'+df['chr'].astype(str)+'_'+df['start'].astype(str)+'_'+df['end'].astype(str)
df = df.drop(['Unnamed: 0'],axis=1)
df
# Compute mCH level
cg = df.iloc[:,3:-1:2]
mcg = df.iloc[:,4:-1:2]
mlevel = mcg.to_numpy() / cg.to_numpy()
hthresh = 10
mlevel[ cg<hthresh ] = np.nan

df_mlevel = pd.DataFrame(mlevel, columns = cg.columns, index=df.enh_pos)
celltypes = df_mlevel.columns
celltypes = [re.sub("(Round2\.|_mCG)","",c) for c in celltypes]
df_mlevel.columns = celltypes
# Cell type names
df_cellnames = pd.read_csv('/cndd/Public_Datasets/CEMBA/BICCN_minibrain_data/data_freeze/supp_info/clusters_final/cluster_annotation_scf_round2.tsv',
                       sep='\t', index_col='cluster')
celltypes_label = df_cellnames.loc[celltypes,'annot']<jupyter_output><empty_output><jupyter_text>Load ATAC data<jupyter_code>atac = pd.read_csv(datadir+'enhancers_reptile_atac_norm.tsv',sep='\t')
atac=atac.set_index('enhancer_idx',drop=False)
atac_enh_list = pd.read_csv(datadir+'enhancers_reptile.bed',sep='\t',header=None,names=['chr','start','end'])
atac = atac.join(atac_enh_list)
atac['enh_pos'] = atac['chr'].astype(str)+'_'+atac['start'].astype(str)+'_'+atac['end'].astype(str)
atac = atac.loc[~(atac['chr']=="chrY")]
df_atac = atac.set_index('enh_pos',drop=False)
# Make sure the ATAC and mCG data are both in the same column order
df_atac = df_atac[celltypes]
df_mlevel = df_mlevel[celltypes]<jupyter_output><empty_output><jupyter_text>Define features<jupyter_code># For each gene, pull all corresponding enhancers
# Get the mean, var etc. of mCG and ATAC levels over all enhancers for each cell type
# This takes ~30 s, so be patient...
features = []
tstart = time.time()
for ensid,r in rna.iterrows():
    curr_enh = genes2enh.loc[ensid]['enh_pos'].values
    
    ml = df_mlevel.loc[curr_enh].values
    ml_mean = np.nanmean(ml,axis=0)
    ml_var = np.nanvar(ml,axis=0)
    ml_max = np.nanmax(ml,axis=0)
    ml_min = np.nanmin(ml,axis=0)
    
    at = df_atac.loc[curr_enh].values
    at_mean = np.nanmean(at,axis=0)
    at_var = np.nanvar(at,axis=0)
    at_max = np.nanmax(at,axis=0)
    at_min = np.nanmin(at,axis=0)
    
    f = np.vstack((ml_mean, ml_var, ml_max,ml_min,
                  at_mean, at_var, at_max,at_min,))
    features.append(f)

print(time.time() - tstart)
farray = np.dstack(features)
features_labels = ['mCG mean','mCG var','mCG max','mCG min',
                   'ATAC mean','ATAC var','ATAC max','ATAC min',]
celltypes = df_mlevel.columns
celltypes = [re.sub("(Round2\.|_mCG)","",c) for c in celltypes]
farray.shape<jupyter_output><empty_output><jupyter_text>Regression<jupyter_code>import sklearn.linear_model as sklm
import matplotlib.pyplot as plt
import scipy
from sklearn.preprocessing import StandardScaler
# For each cell type, correlate the RNA expression with the mean mCG level of all enhancers associated to that gene
cc_mean = []
for celltype_use in celltypes:
    y = rna[celltype_use]
    X = farray[0,celltypes.index(celltype_use),:].squeeze().T
    X.shape, y.shape

    goodgenes = np.isnan(X)==0

    X = X[goodgenes]
    y = y[goodgenes]
    
    cc_mean.append(np.corrcoef(y, X)[0,1])
# For each cell type, regress the RNA expression against mCG features
cc_features = []
coefs = []
for celltype_use in celltypes:
    y = rna[celltype_use]
    X = farray[:,celltypes.index(celltype_use),:].squeeze().T
    X2 = np.nanmedian(farray,axis=1).squeeze().T
    X = np.hstack((X,X2))
    
    goodgenes = np.isnan(X).sum(axis=1)==0
#     print(goodgenes.sum())
    if goodgenes.sum()>100:
        X = X[goodgenes,:]
        y = y[goodgenes]

        #X = scipy.stats.zscore(X, nan_policy='omit')
        X = StandardScaler().fit_transform(X)
        
        regr = sklm.LinearRegression(normalize=False).fit(X,y)

        coefs.append(regr.coef_)
        cc_features.append(np.corrcoef(y, regr.predict(X))[0,1])
    else:
        cc_features.append(np.nan)
plt.plot(cc_features,'o-',label='Regression (mCG+ATAC features)')
plt.plot(cc_mean,'o-',label='Mean mCG only')
plt.legend()
plt.xlabel('Cell type')
plt.ylabel('Correlation coefficient')
features_labels_use = features_labels+[f+' all' for f in features_labels]
features_labels_use
# plt.bar(np.broadcast_to(np.array(features_labels_use).reshape(-1,1), (16,28) ), np.array(coefs).T)
plt.imshow(np.array(coefs).T, vmin=-.05,vmax=.125)
plt.xticks(ticks=np.arange(len(celltypes)), labels=celltypes, rotation=90);
plt.yticks(ticks=np.arange(len(features_labels_use)), labels=features_labels_use);
# plt.yticks(ticks=features_labels_use)
plt.colorbar();
plt.title('Regression coefficients')
plt.bar(features_labels_use, np.array(coefs).mean(axis=0))
plt.plot(features_labels_use, np.array(coefs).T,'k.')
plt.xticks(ticks=np.arange(len(features_labels_use)), labels=features_labels_use,
          rotation=90);
plt.ylabel('Regression coefficients')
plt.grid()
_, ncelltypes, ngenes = farray.shape
X = farray.reshape(-1,ngenes*ncelltypes).T
y = rna[celltypes].to_numpy().reshape(ngenes*ncelltypes,1)
X.shape, farray.shape
# Formula based linear modeling
import statsmodels.formula.api as smf
f0 = np.nanmean(farray,axis=2)
fv = np.nanvar(farray,axis=2)
fz = farray-f0[:,:,np.newaxis]
fz = fz / fv[:,:,np.newaxis]

# fz = farray
# Gather all data into a big DF
data = rna.iloc[:,1:].stack()
data = pd.DataFrame(data, columns=['rna'])

for i,f in enumerate(features_labels):
    d = pd.DataFrame(fz[i,:,:].T, index=rna.index, columns=celltypes)
    d = d.stack()
    d = pd.DataFrame(d, columns=[f])
    data = data.join(d)

data = data.reset_index()
data = data.rename(mapper={'level_1': 'celltype'},axis=1)
dc = data.columns
dc = [re.sub(' ','_',dc1) for dc1 in dc]
data.columns = dc
data = data.loc[data.celltype!="10-1"]
dataz = StandardScaler().fit_transform(data.values[:,2:])
dataz = pd.DataFrame(dataz, index = data.index, columns=data.columns[2:])
dataz['ensid'] = data['ensid']
dataz['celltype'] = data['celltype']
dataz
formula = 'rna ~ 1+celltype'
for c in data.columns[3:]:
    formula += '+'+c
    
# formula = 'rna ~ 1+celltype+mCG_mean+mCG_max+ATAC_mean+ATAC_var'
print(formula)
mdl = smf.ols(formula, dataz).fit()
mdl.summary()
goodgenes = np.isnan(X).sum(axis=1)==0
X = X[goodgenes,:]
y = y[goodgenes]
X.shape,y.shape
regr = sklm.LinearRegression(normalize=False).fit(X,y)
plt.plot(features_labels_use, regr.coef_)
plt.xticks(rotation=90)
yhat = regr.predict(X)
yhat.shape
np.corrcoef(y.T, regr.predict(X).T)<jupyter_output><empty_output><jupyter_text>Reduced rank regression<jupyter_code># Code from: https://github.com/riscy/machine_learning_linear_models/blob/master/reduced_rank_regressor.py
from scipy import sparse

class ReducedRankRegressor(object):
    """
    Reduced Rank Regressor (linear 'bottlenecking' or 'multitask learning')
    - X is an n-by-d matrix of features.
    - Y is an n-by-D matrix of targets.
    - rrank is a rank constraint.
    - reg is a regularization parameter (optional).
    """
    def __init__(self, X, Y, rank, reg=None):
        if np.size(np.shape(X)) == 1:
            X = np.reshape(X, (-1, 1))
        if np.size(np.shape(Y)) == 1:
            Y = np.reshape(Y, (-1, 1))
        if reg is None:
            reg = 0
        self.rank = rank

        CXX = np.dot(X.T, X) + reg * sparse.eye(np.size(X, 1))
        CXY = np.dot(X.T, Y)
        _U, _S, V = np.linalg.svd(np.dot(CXY.T, np.dot(np.linalg.pinv(CXX), CXY)))
        self.W = V[0:rank, :].T
        self.A = np.dot(np.linalg.pinv(CXX), np.dot(CXY, self.W)).T

    def __str__(self):
        return 'Reduced Rank Regressor (rank = {})'.format(self.rank)

    def predict(self, X):
        """Predict Y from X."""
        if np.size(np.shape(X)) == 1:
            X = np.reshape(X, (-1, 1))
        return np.dot(X, np.dot(self.A.T, self.W.T))
Y = rna.values[:,1:]
X = farray.reshape(-1,ngenes).T

# Remove predictors with too many nan values
goodpredictors = np.sum(np.isnan(X),axis=0)<500
X = X[:,goodpredictors]

goodgenes = np.sum(np.isnan(X),axis=1)==0
X = X[goodgenes,:]
Y = Y[goodgenes,:]
X.shape, Y.shape
cc = []
tstart = time.time()
ranks = [1,2,5,10,20]
for rank in ranks:
    regr = ReducedRankRegressor(X,Y,rank)
    Yhat = regr.predict(X)
    cc1 = [np.corrcoef(Y[:,i].T,Yhat[:,i].T)[0,1] for i in range(Y.shape[1])]
    cc.append(cc1)
    print('Rank=%d, time=%3.3f' % (rank, time.time()-tstart))
cc = np.array(cc)
plt.plot(celltypes_label, cc.T);
plt.legend(['Rank='+str(r) for r in ranks])
plt.ylabel('Correlation coefficient')
plt.xticks(rotation=90);
plt.xlabel('Cell type');
plt.grid(axis='y')<jupyter_output><empty_output><jupyter_text>Kmers<jupyter_code># Get fasta file
import scipy
import sklearn
from matplotlib import pyplot as plt
kdict=np.load(datadir+'kmers_6mers/kmer_dict.npy', allow_pickle=True)
# Load the kmer data per enhancer
kmer_counts=np.load(datadir+'kmers_6mers/count.npy')
kdict=np.load(datadir+'kmers_6mers/kmer_dict.npy')
kmer_enh = pd.read_csv(datadir+'enhancers_reptile.bed', sep='\t', 
                       header=None, columns=['chr','start','end'])
kmer_enh['enh_pos'] = ['_'.join([str(i) for i in row]) for ind,row in kmer_enh.iterrows()]
kmer_enh['enh_num'] = np.arange(kmer_enh.shape[0])
kmer_enh = kmer_enh.set_index('enh_pos', drop=False)
kmer_enh, kmer_counts.shape
# Subset to the HVGs
genes2enhu = genes2enh.loc[rna.index]
# Determine the enhancer number for each gene-enhancer pair
genes2enhu['enh_num'] = kmer_enh.loc[genes2enhu['enh_pos'],'enh_num'].values
kmer_countsu = kmer_counts[genes2enhu['enh_num'],:]
df_mlevelu = df_mlevel.loc[genes2enhu['enh_pos']]
df_atacu = df_atac.loc[genes2enhu['enh_pos']]
kmer_countsu.shape, df_mlevelu.shape, df_atacu.shape
rna.shape, kmer_countsu.shape
ensid = 'ENSMUSG00000067879'

y = rna.loc[ensid,:]

curr_enh = genes2enh.loc[ensid]['enh_pos'].values
curr_enh_num = kmer_enh.loc[curr_enh,'enh_num']
curr_kmers = kmer_counts[curr_enh_num,:]
curr_atac = df_atac.loc[curr_enh,:]
curr_mcg = df_mlevel.loc[curr_enh,:]
curr_kmers.shape, curr_atac.shape, curr_mcg.shape
mdl = sklearn.linear_model.ElasticNet()
curr_enh = genes2enh.loc[ensid]['enh_pos'].values
curr_enh
# Link K-mers to genes
features = []
tstart = time.time()
for ensid,r in rna.iterrows():
    curr_enh = genes2enh.loc[ensid]['enh_pos'].values
    
    ml = df_mlevel.loc[curr_enh].values
    ml_mean = np.nanmean(ml,axis=0)
    ml_var = np.nanvar(ml,axis=0)<jupyter_output><empty_output><jupyter_text>PyTorch<jupyter_code># Make sure all data frames have the cell types in the same order
enh_posu = genes2enhu['enh_pos'].unique()
df_mlevelu = df_mlevel.loc[enh_posu]
df_atacu = df_atac.loc[enh_posu]
df_mlevelu
rnau = rna.drop(['10-1','Unnamed: 0'],axis=1)
df_mlevelu = df_mlevelu.loc[:,rnau.columns]
df_atacu = df_atacu.loc[:,rnau.columns]
df_mlevelu  = df_mlevelu.drop_duplicates()
df_atacu = df_atacu.drop_duplicates()
assert( (rnau.columns==df_mlevelu.columns).all() )
assert( (rnau.columns==df_atacu.columns).all() )
df_mlevelu.shape, df_atacu.shape
# Train a CNN regression to predict the mCG level of all DMRs
import pandas as pd
import csv
import numpy as np
import time
import matplotlib.pyplot as plt
# import seqlogo
# from IPython.display import clear_output
# import datetime
# from scipy.stats import spearmanr

import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim

torch.cuda.is_available()
# Impute the NaN values in mlevel
df_mlevelu_mean = np.outer(df_mlevelu.median(axis=1).values, df_mlevelu.median(axis=0).values)
df_mlevelu_mean = pd.DataFrame(df_mlevelu_mean, index=df_mlevelu.index, columns=df_mlevelu.columns)
df_mlevelu_mean = df_mlevelu_mean.fillna(df_mlevelu.median())
df_mlevelu = df_mlevelu.fillna(df_mlevelu_mean)
assert(not df_mlevelu.isna().any(axis=None))
assert(not df_atacu.isna().any(axis=None))
kmer_counts.shape, kmer_countsu.shape
# Define the neural net architecture
nfilt = 10;
filt_width = 10
pool_size = 600

C = y.shape[1] # Number of cell types
K = kmer_countsu.shape[1] # Number of K-mers

def get_data(ensid):
    # For a list of ensids, return the x and y features
    x = []
    for i,ens in enumerate(ensid):
        curr_enh = genes2enhu.loc[ens,['enh_pos','enh_num']]
#         E = curr_enh.groupby('ensid').count().max(axis=0);
        mlu = df_mlevelu.loc[curr_enh['enh_pos']]
        atacu = df_atacu.loc[curr_enh['enh_pos']]
        kmeru = kmer_counts[curr_enh['enh_num']]
        Ne,Nk = kmeru.shape
        Nc = mlu.shape[1]
        kmeru = kmeru[:,np.newaxis,:]
        kmeru = np.broadcast_to(kmeru,(Ne,Nc,Nk))
        x1 = np.dstack((mlu,atacu,kmeru))
        x1 = x1[np.newaxis,:,:,:]
        x.append(x1)
    
    # Pad the dimensions
    max_nenh = np.max([xi.shape[1] for xi in x])
    xpad = []
    for xi in x:
        xpad.append(np.pad(xi, ((0,0),(0,max_nenh-xi.shape[1]),(0,0),(0,0))))
    x = np.concatenate(xpad, axis=0)

    y = rnau.loc[ensid].to_numpy().squeeze()
    
    x = torch.tensor(x, dtype=torch.float)
    y = torch.tensor(y, dtype=torch.float)
    
    return {'x': x, 'y': y}
data=get_data(ensids[indices])
data['y'].shape
# get_data(ensids[indices[9:11]])
ensids[indices[9]]
get_data(['ENSMUSG00000026141'])
N1 = 10
N2 = 5

# Define a class for the NN architecture
class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        
        self.fc1 = nn.Linear(2+K, N1);
        self.fc2 = nn.Linear(N1, N2);
        self.fc2 = nn.Linear(N1, N2);
        self.fc3 = nn.Linear(N2, 1);
        
    def forward(self, x): 
#         x should be mcg, atac, kmers
#         In: [mcg, atac, kmers] = N x Eg x (2+K)
        x = F.relu(self.fc1(x)) # In: N x Eg x C x (2+K), Out: N x Eg x C x N1
        x = torch.max(x, 1)[0]       # Out: N x C x N1
        x = F.relu(self.fc2(x))       # Out: N x C x N2
        x = torch.squeeze(self.fc3(x)) # Out: N x C
        
        return x

net = Net()
outputs = net(data['x'])
data['x'].shape
# Training
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
if device is not "cpu":
    net.to(torch.device(device))
mseloss=nn.MSELoss()
lr = 0.01
optimizer = optim.SGD(net.parameters(), lr=lr, momentum=0.9)

if device is not "cpu":
    net.to(device)
net.train
running_time = 0
loss_vec = corr_vec = []
nepochs = 0
scheduler = optim.lr_scheduler.ReduceLROnPlateau(optimizer)

loss_test=np.array([])
loss_train = np.array([])
nparams = np.array([])
l1params = np.array([])

# Train/Test split
test = [c in ['chr10','chr12','chr14'] for c in rnau.join(genes)['chr']];
train = [not i for i in test]

test = np.random.permutation(np.nonzero(test)[0]).squeeze()
train = np.random.permutation(np.nonzero(train)[0]).squeeze()

ensids = rna.index.values

test.max(), train.max()
# test = [c in ['chr10','chr12','chr14'] for c in rnau.join(genes)['chr']];
np.nonzero(test)[0].max()
%load_ext line_profiler
%lprun -f get_data get_data([ensids[0]])
# %lprun?
criterion = nn.MSELoss()
num_epochs = 10;
batch_size = 1;

t0 = time.time()
for epoch in range(num_epochs):  # loop over the dataset multiple times
    nsamp = 0
    running_loss = 0;
    running_time = 0
    for i in range(0, len(train), batch_size):
        tstart = time.time()
        indices = train[i:i+batch_size]

        # Input should be of size: (batch, channels, samples)
        batch_data = get_data(ensids[indices])
        batch_X = batch_data['x']
        batch_y = batch_data['y']

        # Send training data to CUDA
        if device is not "cpu":
            batch_X = batch_X.to(device)
            batch_y = batch_y.to(device)

        # zero the parameter gradients
        optimizer.zero_grad()

        # forward + backward + optimize
        outputs = net(batch_X)
        loss = criterion(outputs, batch_y)
        loss.backward()
        optimizer.step()
        
        running_loss += mseloss(outputs, batch_dmrs_mc).item()

        running_time += time.time()-tstart
        nsamp += len(indices)
        if (time.time()-t0)>5:
            print('Epoch %d, i=%d/%d, loss=%3.3f, t=%3.3f, %3.3f s/sample' % (epoch, i, len(train), 
                                                                              running_loss/nsamp, running_time, running_time/nsamp))
            t0=time.time()
    loss_train = np.append(loss_train,running_loss/nsamp)

nsamp
ensid = ensids[indices[8]]
rnau.loc[ensids[indices[8]]]
df_mlevelu.loc[genes2enhu.loc[ensid]['enh_pos']]
# df_atacu.loc[genes2enhu.loc[ensid]['enh_pos']]
kmer_countsu.shape<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.16360592532467533, 'fraction_numerical': 0.01567573051948052, 'mean_word_length': 4.030109721867824, 'pattern_counts': {'":': 3, '<': 44, '<?xml version=': 0, '>': 44, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 3, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '10', 'dir': 'jupyter-structured-clean-dedup', 'id': '456124', 'license': 'MIT', 'n_tokens_mistral': 8103, 'n_tokens_neox': 7866, 'n_words': 1397, 'path': 'eran/Regress_Enhancers_ReducedRank.ipynb', 'repo_name': 'FangmingXie/scf_enhancer_paper', 'size': '19712'}