Skip to content

Commit

Permalink
Add Python2 support
Browse files Browse the repository at this point in the history
  • Loading branch information
cangermueller committed Feb 19, 2017
1 parent d008246 commit 9020fd5
Show file tree
Hide file tree
Showing 35 changed files with 195 additions and 76 deletions.
6 changes: 3 additions & 3 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ DeepCpG: Deep neural networks for predicting single-cell DNA methylation

|Version| |License| |PyPI| |Docs| |Tweet|

.. |Version| image:: https://img.shields.io/badge/python-3.5%2B-green.svg
.. |Version| image:: https://img.shields.io/badge/python-2.7%2B%2C3.4%2B-green.svg
:target: https://www.python.org/

.. |License| image:: https://img.shields.io/github/license/mashape/apistatus.svg
:target: https://github.com/cangermueller/deepcpg/tree/master/LICENSE

.. |PyPI| image:: https://img.shields.io/pypi/v/nine.svg?style=plastic
:target: https://pypi.python.org/pypi/deepcpg/1.0.1
.. |PyPI| image:: https://img.shields.io/badge/pypi-latest-orange.svg
:target: https://pypi.python.org/pypi/deepcpg

.. |Docs| image:: https://img.shields.io/badge/docs-up--to--date-green.svg
:target: http://deepcpg.readthedocs.io
Expand Down
2 changes: 1 addition & 1 deletion deepcpg/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = '1.0.1'
__version__ = '1.0.2'
30 changes: 15 additions & 15 deletions deepcpg/callbacks.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
from __future__ import division
from __future__ import print_function

from collections import OrderedDict
import os
from pkg_resources import parse_version
from time import time

from keras import backend as K
from keras.callbacks import Callback

import numpy as np
import six

from .utils import format_table, EPS

Expand All @@ -17,8 +19,6 @@ class PerformanceLogger(Callback):
Stores and prints performance metrics for each batch, epoch, and output.
"""



def __init__(self, metrics=['loss', 'acc'], log_freq=0.1,
precision=4, callbacks=[], verbose=1, logger=print):
self.metrics = metrics
Expand Down Expand Up @@ -78,7 +78,7 @@ def _init_logs(self, logs, train=True):
for mean_name in metrics:
logs_dict[mean_name] = []
# Followed by all output metrics
for mean_name, names in metrics.items():
for mean_name, names in six.iteritems(metrics):
for name in names:
logs_dict[name] = []

Expand All @@ -87,7 +87,7 @@ def _init_logs(self, logs, train=True):
def _update_means(self, logs, metrics):
"""Computes the mean over all outputs, if it does not exist yet."""

for mean_name, names in metrics.items():
for mean_name, names in six.iteritems(metrics):
# Skip, if mean already exists, e.g. loss.
if logs[mean_name][-1] is not None:
continue
Expand Down Expand Up @@ -138,7 +138,7 @@ def on_epoch_end(self, epoch, logs={}):
self._val_epoch_metrics, self.val_epoch_logs = tmp

# Add new epoch logs to logs table
for metric, metric_logs in self.epoch_logs.items():
for metric, metric_logs in six.iteritems(self.epoch_logs):
if metric in logs:
metric_logs.append(logs[metric])
else:
Expand All @@ -147,7 +147,7 @@ def on_epoch_end(self, epoch, logs={}):
self._update_means(self.epoch_logs, self._epoch_metrics)

# Add new validation epoch logs to logs table
for metric, metric_logs in self.val_epoch_logs.items():
for metric, metric_logs in six.iteritems(self.val_epoch_logs):
metric_val = 'val_' + metric
if metric_val in logs:
metric_logs.append(logs[metric_val])
Expand All @@ -163,15 +163,15 @@ def on_epoch_end(self, epoch, logs={}):
table[mean_name] = []
# Show output logs
if self.verbose:
for mean_name, names in self._epoch_metrics.items():
for mean_name, names in six.iteritems(self._epoch_metrics):
for name in names:
table[name] = []
for name, logs in self.epoch_logs.items():
for name, logs in six.iteritems(self.epoch_logs):
if name in table:
table[name].append(logs[-1])
if self.val_epoch_logs:
table['split'].append('val')
for name, logs in self.val_epoch_logs.items():
for name, logs in six.iteritems(self.val_epoch_logs):
if name in table:
table[name].append(logs[-1])
self._log('')
Expand All @@ -196,12 +196,12 @@ def on_batch_end(self, batch, logs={}):
self._totals = OrderedDict()
# Number of samples up to the current batch
self._nb_totals = OrderedDict()
for name in self._batch_logs.keys():
for name in self._batch_logs:
if name in logs:
self._totals[name] = 0
self._nb_totals[name] = 0

for name, value in logs.items():
for name, value in six.iteritems(logs):
# Skip value if nan, which can occur if the batch size is small.
if np.isnan(value):
continue
Expand Down Expand Up @@ -241,11 +241,11 @@ def on_batch_end(self, batch, logs={}):
for mean_name in self._batch_metrics:
table[mean_name] = []
if self.verbose:
for mean_name, names in self._batch_metrics.items():
for mean_name, names in six.iteritems(self._batch_metrics):
for name in names:
table[name] = []
precision.append(self.precision)
for name, logs in self._batch_logs.items():
for name, logs in six.iteritems(self._batch_logs):
if name in table:
table[name].append(logs[-1])
precision.append(self.precision)
Expand Down
6 changes: 4 additions & 2 deletions deepcpg/data/annotations.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
from __future__ import division
from __future__ import print_function

import pandas as pd
import numpy as np
import sys
from six.moves import range


def read_bed(filename, sort=False, usecols=[0, 1, 2], *args, **kwargs):
Expand Down Expand Up @@ -130,7 +133,6 @@ def group_overlapping(s, e):
if n == 0:
return group
idx = 0
l = s[0]
r = e[0]
for i in range(1, n):
if s[i] > r:
Expand Down
4 changes: 4 additions & 0 deletions deepcpg/data/dna.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
from __future__ import division
from __future__ import print_function

from collections import OrderedDict

import numpy as np
from six.moves import range

CHAR_TO_INT = OrderedDict([('A', 0), ('T', 1), ('G', 2), ('C', 3), ('N', 4)])
INT_TO_CHAR = {v: k for k, v in CHAR_TO_INT.items()}
Expand Down
5 changes: 5 additions & 0 deletions deepcpg/data/fasta.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
from __future__ import division
from __future__ import print_function

import os
from glob import glob
import gzip as gz

from six.moves import range

from ..utils import to_list


Expand Down
4 changes: 4 additions & 0 deletions deepcpg/data/feature_extractor.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
from __future__ import division
from __future__ import print_function

import numpy as np
from six.moves import range


class KnnCpgFeatureExtractor(object):
Expand Down
15 changes: 10 additions & 5 deletions deepcpg/data/hdf.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
from __future__ import division
from __future__ import print_function

import re

import h5py as h5
import numpy as np
import six
from six.moves import range

from ..utils import filter_regex, to_list

Expand Down Expand Up @@ -38,7 +43,7 @@ def ls(filename, group='/', recursive=False, groups=False,
def write_data(data, filename):
is_root = isinstance(filename, str)
group = h5.File(filename, 'w') if is_root else filename
for key, value in data.items():
for key, value in six.iteritems(data):
if isinstance(value, dict):
key_group = group.create_group(key)
write_data(value, key_group)
Expand All @@ -50,7 +55,7 @@ def write_data(data, filename):

def hnames_to_names(hnames):
names = []
for key, value in hnames.items():
for key, value in six.iteritems(hnames):
if isinstance(value, dict):
for name in hnames_to_names(value):
names.append('%s/%s' % (key, name))
Expand Down Expand Up @@ -113,7 +118,7 @@ def reader(data_files, names, batch_size=128, nb_sample=None, shuffle=False,
# the entire file into memory
idx = np.arange(nb_sample_file)
np.random.shuffle(idx)
for name, value in data_file.items():
for name, value in six.iteritems(data_file):
data_file[name] = value[:len(idx)][idx]

nb_batch = int(np.ceil(nb_sample_file / batch_size))
Expand Down Expand Up @@ -162,7 +167,7 @@ def read_from(reader, nb_sample=None):
if not isinstance(data_batch, dict):
data_batch = _to_dict(data_batch)
is_dict = False
for key, value in data_batch.items():
for key, value in six.iteritems(data_batch):
values = data.setdefault(key, [])
values.append(value)
nb_seen += len(list(data_batch.values())[0])
Expand All @@ -171,7 +176,7 @@ def read_from(reader, nb_sample=None):

data = stack_dict(data)
if nb_sample:
for key, value in data.items():
for key, value in six.iteritems(data):
data[key] = value[:nb_sample]

if not is_dict:
Expand Down
3 changes: 3 additions & 0 deletions deepcpg/data/stats.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
* [sites, cells, context] for window-based statistics
"""

from __future__ import division
from __future__ import print_function

import numpy as np

from ..utils import EPS, get_from_module
Expand Down
12 changes: 10 additions & 2 deletions deepcpg/data/utils.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
from __future__ import division
from __future__ import print_function

import gzip
import threading
import re

import h5py as h5
import numpy as np
import pandas as pd
import six
from six.moves import range

from . import hdf

Expand All @@ -27,6 +32,9 @@ def __next__(self):
with self.lock:
return next(self.it)

def next(self):
return self.__next__()


def threadsafe_generator(f):
"""A decorator that takes a generator function and makes it thread-safe.
Expand All @@ -37,7 +45,7 @@ def g(*a, **kw):


def add_to_dict(src, dst):
for key, value in src.items():
for key, value in six.iteritems(src):
if isinstance(value, dict):
if key not in dst:
dst[key] = dict()
Expand All @@ -50,7 +58,7 @@ def add_to_dict(src, dst):

def stack_dict(data):
sdata = dict()
for key, value in data.items():
for key, value in six.iteritems(data):
if isinstance(value, dict):
sdata[key] = stack_dict(value)
else:
Expand Down
6 changes: 5 additions & 1 deletion deepcpg/evaluation.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
from __future__ import division
from __future__ import print_function

from collections import OrderedDict

import numpy as np
import pandas as pd
import sklearn.metrics as skm
from scipy.stats import kendalltau
from six.moves import range

from .data import CPG_NAN, OUTPUT_SEP
from .utils import get_from_module
Expand Down Expand Up @@ -147,7 +151,7 @@ def get_output_metrics(output_name):

def evaluate_outputs(outputs, preds):
perf = []
for output_name in outputs.keys():
for output_name in outputs:
_output_name = output_name.split(OUTPUT_SEP)
if _output_name[-1] in ['cat_var']:
tmp = evaluate_cat(outputs[output_name],
Expand Down
3 changes: 3 additions & 0 deletions deepcpg/metrics.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
from __future__ import division
from __future__ import print_function

from keras import backend as K

from .utils import get_from_module
Expand Down
3 changes: 3 additions & 0 deletions deepcpg/models/cpg.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
cells.
"""

from __future__ import division
from __future__ import print_function

import inspect

from keras import layers as kl
Expand Down
15 changes: 9 additions & 6 deletions deepcpg/models/dna.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
Provides models trained with DNA sequence windows.
"""

from __future__ import division
from __future__ import print_function

import inspect

from keras import layers as kl
Expand Down Expand Up @@ -197,7 +200,7 @@ class ResNet01(DnaModel):
Parameters: 1.700.000
He et al., Identity Mappings in Deep Residual Networks.
He et al., 'Identity Mappings in Deep Residual Networks.'
"""

def _res_unit(self, inputs, nb_filter, size=3, stride=1, stage=1, block=1):
Expand Down Expand Up @@ -290,7 +293,7 @@ class ResNet02(ResNet01):
Parameters: 2.000.000
He et al., Identity Mappings in Deep Residual Networks.
He et al., 'Identity Mappings in Deep Residual Networks.'
"""

def __call__(self, inputs):
Expand Down Expand Up @@ -334,7 +337,7 @@ class ResConv01(ResNet01):
Parameters: 2.800.000
He et al., Identity Mappings in Deep Residual Networks.
He et al., 'Identity Mappings in Deep Residual Networks.'
"""

def _res_unit(self, inputs, nb_filter, size=3, stride=1, stage=1, block=1):
Expand Down Expand Up @@ -419,8 +422,8 @@ class ResAtrous01(DnaModel):
Parameters: 2.000.000
He et al., Identity Mappings in Deep Residual Networks.
Yu and Koltun, Multi-Scale Context Aggregation by Dilated Convolutions.
He et al., 'Identity Mappings in Deep Residual Networks.'
Yu and Koltun, 'Multi-Scale Context Aggregation by Dilated Convolutions.'
"""

def _res_unit(self, inputs, nb_filter, size=3, stride=1, atrous=1,
Expand Down Expand Up @@ -515,7 +518,7 @@ def __call__(self, inputs):
def list_models():
models = dict()
for name, value in globals().items():
if inspect.isclass(value) and name.lower().find('model') == -1:
if inspect.isclass(value) and name.lower().find('model') == 0:
models[name] = value
return models

Expand Down
3 changes: 3 additions & 0 deletions deepcpg/models/joint.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
from __future__ import division
from __future__ import print_function

from keras import layers as kl
from keras import models as km
from keras import regularizers as kr
Expand Down

0 comments on commit 9020fd5

Please sign in to comment.