Skip to content

Commit 7451274

Browse files
committed
Merge branch 'release/0.18.0'
2 parents 6205d50 + 149d79c commit 7451274

101 files changed

Lines changed: 4888 additions & 4819 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CHANGELOG.md

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,51 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).
55

66
## Unreleased
77

8+
## [0.18.0] - 2023-01-11
9+
10+
### Added
11+
12+
- `gimme scan` and `gimme maelstrom` now accept a random seed for (most) operations
13+
- for (optimal) deterministic behaviour, delete the cache and then run the command with a seed
14+
- `Scanner` now accepts a `np.random.RandomState` and `progress` on init.
15+
- `progress=None` (the default) should print progress bars to the command line only, not to file.
16+
- `Scanner.set_genome` now accepts the optional argument `genomes_dir`
17+
- `gimmemotifs.maelstrom.Moap.create` now accepts a `np.random.RandomState`.
18+
- `gimmemotifs.maelstrom.run_maelstrom` now accepts a `np.random.RandomState`.
19+
20+
### Changed
21+
22+
- `gimme diff` (`diff_plot()` to be exact) will now print to stdout, like all other functions
23+
- now using the logger instead of print/sys.stderr.write in many more places
24+
- string formatting now (mostly) done with f-strings
25+
- refactored Fasta class
26+
- split `scanner.py` into 3 submodules:
27+
- `scanner/__init__.py` with the exported functions
28+
- `scanner/base.py` with the Scanner class
29+
- `scanner/utils.py` with the rest
30+
- `gimmemotifs/maelstrom.py` renamed to `gimmemotifs/maelstrom/_init__.py`
31+
- `rank.py` and `moap.py` are now submodules of maelstrom.
32+
33+
### Fixed
34+
35+
- `gimme maelstrom` works with or without xgboost (but will give a warning without xgboost)
36+
- fixed warning "in validate_matrix(): Row sums in df are not close to 1. Reormalizing rows..."
37+
- fixed multiprocess.Pool Warnings
38+
- fixed a pandas copywarning (in `gc_bin_bedfile()` to be exact)
39+
- fixed warnings when leaving files open
40+
- fixed deprecation warning in maelstrom (and in tests)
41+
- fixed futurewarning in report.py
42+
- silence warnings from external tools in motif prediction (`pp_predict_motifs()` to be exact)
43+
- updated last references from `Motif.pwm_scan` and `Motif.pwm_scan_all` to `Motif.scan` and `Motif.scan_all` respectively
44+
- typo in `gimme motifs` output ("%matches background" to "% matches background")
45+
- `Scanner` now uses a cheaper method to determine a genome's identity
46+
- (filesize + name instead of the md5sum of the whole genome's contents)
47+
- `gimme motifs` gives an informative error when `fraction` is not within 0-1.
48+
- `gimme threshold` works again
49+
50+
### Removed
51+
52+
- removed old python2 code (scanning with MOODS & import shenanigans)
853

954
## [0.17.2] - 2022-10-12
1055

compile_externals.py

Lines changed: 28 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
import sys
21
import os
3-
from subprocess import Popen, PIPE
2+
import sys
43
from distutils import log
4+
from subprocess import PIPE, Popen
55

66

77
def compile_simple(name, src_dir="src"):
@@ -23,37 +23,35 @@ def compile_simple(name, src_dir="src"):
2323
except Exception:
2424
return
2525

26-
Popen(
27-
[gcc, "-o%s" % name, "%s.c" % name, "-lm"], cwd=path, stdout=PIPE
28-
).communicate()
26+
Popen([gcc, f"-o{name}", f"{name}.c", "-lm"], cwd=path, stdout=PIPE).communicate()
2927
if os.path.exists(os.path.join(path, name)):
3028
return True
3129

3230

33-
def compile_configmake(name, binary, configure=True, src_dir="src"):
34-
path = os.path.join(src_dir, "%s" % name)
35-
36-
if not os.path.exists(path):
37-
return
38-
39-
if configure:
40-
Popen(
41-
["chmod", "+x", "./configure"], cwd=path, stdout=PIPE, stderr=PIPE
42-
).communicate()
43-
stdout, stderr = Popen(
44-
["./configure"], cwd=path, stdout=PIPE, stderr=PIPE
45-
).communicate()
46-
print(stdout)
47-
print(stderr)
48-
49-
stdout, stderr = Popen(
50-
["make -j 4"], cwd=path, stdout=PIPE, stderr=PIPE, shell=True
51-
).communicate()
52-
print(stdout)
53-
print(stderr)
54-
55-
if os.path.exists(os.path.join(path, binary)):
56-
return True
31+
# def compile_configmake(name, binary, configure=True, src_dir="src"):
32+
# path = os.path.join(src_dir, str(name))
33+
#
34+
# if not os.path.exists(path):
35+
# return
36+
#
37+
# if configure:
38+
# Popen(
39+
# ["chmod", "+x", "./configure"], cwd=path, stdout=PIPE, stderr=PIPE
40+
# ).communicate()
41+
# stdout, stderr = Popen(
42+
# ["./configure"], cwd=path, stdout=PIPE, stderr=PIPE
43+
# ).communicate()
44+
# print(stdout)
45+
# print(stderr)
46+
#
47+
# stdout, stderr = Popen(
48+
# ["make -j 4"], cwd=path, stdout=PIPE, stderr=PIPE, shell=True
49+
# ).communicate()
50+
# print(stdout)
51+
# print(stderr)
52+
#
53+
# if os.path.exists(os.path.join(path, binary)):
54+
# return True
5755

5856

5957
def print_result(result):
@@ -63,10 +61,7 @@ def print_result(result):
6361
log.info("... ok")
6462

6563

66-
def compile_all(prefix=None, src_dir="src"):
67-
# are we in the conda build environment?
68-
conda_build = os.environ.get("CONDA_BUILD")
69-
64+
def compile_all(src_dir="src"):
7065
sys.stderr.write("compiling BioProspector")
7166
sys.stderr.flush()
7267
result = compile_simple("BioProspector", src_dir=src_dir)

docs/api.rst

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ Now we can use this file for scanning.
238238
f = Fasta("test.fa")
239239
m = motif_from_consensus("TGAsTCA")
240240
241-
m.pwm_scan(f)
241+
m.scan(f)
242242
243243
.. code-block:: python
244244
@@ -247,11 +247,11 @@ Now we can use this file for scanning.
247247
This return a dictionary with the sequence names as keys.
248248
The value is a list with positions where the motif matches.
249249
Here, as the AP1 motif is a palindrome, you see matches on both forward and reverse strand.
250-
This is more clear when we use ``pwm_scan_all()`` that returns position, score and strand for every match.
250+
This is more clear when we use ``scan_all()`` that returns position, score and strand for every match.
251251

252252
.. code-block:: python
253253
254-
m.pwm_scan_all(f)
254+
m.scan_all(f)
255255
256256
.. code-block:: python
257257
@@ -267,7 +267,7 @@ Use ``scan_rc=False`` to only scan the forward orientation.
267267

268268
.. code-block:: python
269269
270-
m.pwm_scan_all(f, nreport=1, scan_rc=False)
270+
m.scan_all(f, nreport=1, scan_rc=False)
271271
272272
.. code-block:: python
273273
@@ -295,7 +295,7 @@ If you only want the best match per sequence, is a utility function called ``sca
295295
result = scan_to_best_match("test.fa", motifs)
296296
for motif, matches in result.items():
297297
for match in matches:
298-
print("{}\t{}\t{}".format(motif, match[1], match[0]))
298+
print(f"{motif}\t{match[1]}\t{match[0]}")
299299
300300
.. code-block:: python
301301

docs/conf.py

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,13 @@
1212

1313
import os
1414
import sys
15-
import mock
1615

16+
import mock # noqa: available on readthedocs
1717

18-
sys.path.insert(0, os.path.abspath('..'))
18+
sys.path.insert(0, os.path.abspath(".."))
1919
# c_metrics is created, but rtd can't find it for some reason
2020
# to fix this we do a mock import
21-
MOCK_MODULES = ['gimmemotifs.c_metrics']
21+
MOCK_MODULES = ["gimmemotifs.c_metrics"]
2222
for mod_name in MOCK_MODULES:
2323
sys.modules[mod_name] = mock.Mock()
2424

@@ -30,9 +30,9 @@
3030

3131
# -- Project information -----------------------------------------------------
3232

33-
project = 'GimmeMotifs'
34-
copyright = '2022, Simon van Heeringen, licensed under CC BY 4.0'
35-
author = 'Simon van Heeringen, Siebren Frölich, Maarten van der Sande'
33+
project = "GimmeMotifs"
34+
copyright = "2022, Simon van Heeringen, licensed under CC BY 4.0"
35+
author = "Simon van Heeringen, Siebren Frölich, Maarten van der Sande"
3636

3737
# Major, minor and hotfix versions
3838
version = __version__.split("+")[0]
@@ -46,20 +46,20 @@
4646
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
4747
# ones.
4848
extensions = [
49-
'sphinx.ext.autodoc', # automatic documentation from docstrings
50-
'sphinx.ext.coverage', # gather documentation coverage stats
51-
'sphinx.ext.napoleon', # recognize numpy & google style docstrings
52-
'sphinx.ext.autosummary', # Create neat summary tables
49+
"sphinx.ext.autodoc", # automatic documentation from docstrings
50+
"sphinx.ext.coverage", # gather documentation coverage stats
51+
"sphinx.ext.napoleon", # recognize numpy & google style docstrings
52+
"sphinx.ext.autosummary", # Create neat summary tables
5353
# 'numpydoc',
5454
]
5555

5656
# Add any paths that contain templates here, relative to this directory.
57-
templates_path = ['_templates']
57+
templates_path = ["_templates"]
5858

5959
# List of patterns, relative to source directory, that match files and
6060
# directories to ignore when looking for source files.
6161
# This pattern also affects html_static_path and html_extra_path.
62-
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
62+
exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"]
6363

6464

6565
# -- Options for HTML output -------------------------------------------------
@@ -72,7 +72,7 @@
7272
# Add any paths that contain custom static files (such as style sheets) here,
7373
# relative to this directory. They are copied after the builtin static files,
7474
# so a file named "default.css" will overwrite the builtin "default.css".
75-
html_static_path = ['_static']
75+
html_static_path = ["_static"]
7676

7777

7878
# -- Extension configuration -------------------------------------------------

docs/notebooks/api_examples.ipynb

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -387,7 +387,7 @@
387387
"cell_type": "markdown",
388388
"metadata": {},
389389
"source": [
390-
"To convert a motif to an image, use `to_img()`. Supported formats are png, ps and pdf."
390+
"To convert a motif to an image, use `plot_logo()`. Supported formats are png, ps and pdf."
391391
]
392392
},
393393
{
@@ -397,7 +397,7 @@
397397
"outputs": [],
398398
"source": [
399399
"m = motif_from_consensus(\"NTGASTCAN\")\n",
400-
"m.to_img(\"ap1.png\", fmt=\"png\")"
400+
"m.plot_logo(\"ap1.png\", fmt=\"png\")"
401401
]
402402
},
403403
{
@@ -465,14 +465,14 @@
465465
"f = Fasta(\"test.small.fa\")\n",
466466
"m = motif_from_consensus(\"TGAsTCA\")\n",
467467
"\n",
468-
"m.pwm_scan(f)"
468+
"m.scan(f)"
469469
]
470470
},
471471
{
472472
"cell_type": "markdown",
473473
"metadata": {},
474474
"source": [
475-
"This return a dictionary with the sequence names as keys. The value is a list with positions where the motif matches. Here, as the AP1 motif is a palindrome, you see matches on both forward and reverse strand. This is more clear when we use `pwm_scan_all()` that returns position, score and strand for every match."
475+
"This return a dictionary with the sequence names as keys. The value is a list with positions where the motif matches. Here, as the AP1 motif is a palindrome, you see matches on both forward and reverse strand. This is more clear when we use `scan_all()` that returns position, score and strand for every match."
476476
]
477477
},
478478
{
@@ -497,7 +497,7 @@
497497
}
498498
],
499499
"source": [
500-
"m.pwm_scan_all(f)"
500+
"m.scan_all(f)"
501501
]
502502
},
503503
{
@@ -526,7 +526,7 @@
526526
}
527527
],
528528
"source": [
529-
"m.pwm_scan_all(f, nreport=1, scan_rc=False)"
529+
"m.scan_all(f, nreport=1, scan_rc=False)"
530530
]
531531
},
532532
{

docs/release_checklist.md

Lines changed: 38 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,26 +4,39 @@ This is mainly for personal use at the moment.
44

55
##
66

7-
1. Create release candidate with `git flow`.
87

9-
```
10-
$ git flow release start ${new_version}
8+
1. Make sure all tests pass.
9+
10+
```shell
11+
mamba env update -f environment.yml
12+
pytest -vvv
1113
```
1214

13-
2. Update version in `gimmemotifs/config.py`
15+
2. Create release candidate with `git flow`:
16+
17+
```shell
18+
new_version=0.0.0
19+
echo ${new_version}
20+
21+
git flow release start ${new_version}
22+
```
1423

1524
3. Make sure `CHANGELOG.md` is up-to-date.
1625

26+
* add the new version & date to the header
27+
* link to the diff in the footer
28+
* add & commit the changes, but do not push
29+
1730
4. Test install using pip in fresh conda environment
1831

32+
```shell
33+
python setup.py sdist
34+
mamba create -n test python=3.9 pytest
35+
mamba activate test
36+
pip install dist/gimmemotifs*.tar.gz
37+
pytest -vvv
1938
```
20-
$ cd ${test_dir} # Not the gimmemotifs git directory
21-
$ conda create -n testenv python=3 --file requirements.yaml
22-
$ conda activate testenv
23-
$ pip install -e git+https://github.com/simonvh/gimmemotifs.git@release/${version}#egg=gimmemotifs
24-
$ cd src/gimmemotifs
25-
$ python run_tests.py
26-
```
39+
2740
5. Upload to pypi testing server
2841

2942
```
@@ -37,20 +50,27 @@ $ twine upload -r testpypi dist/gimmemotifs-${version}.tar.gz
3750

3851
6. Finish release
3952

53+
```shell
54+
git flow release finish ${new_version}
4055
```
41-
$ git flow release finish ${version}
42-
```
4356

44-
7. Upload to PyPi.
4557

58+
7. Push everything to github, including tags:
59+
60+
```shell
61+
git push --follow-tags origin develop master
4662
```
47-
$ python setup.py sdist
48-
$ twine upload dist/gimmemotifs-${version}.tar.gz
63+
64+
8. Upload to PyPi.
65+
66+
```shell
67+
python setup.py sdist
68+
twine upload dist/gimmemotifs-${new_version}.tar.gz
4969
```
5070

51-
8. Finalize the release on Github.
71+
9. Finalize the release on Github.
5272

5373
Create a release. Download the tarball and then edit the release and attach the
5474
tarball as binary.
5575

56-
8. Create bioconda package
76+
10. Update the Bioconda package recipe

0 commit comments

Comments
 (0)