fp-tools-bio 0.1.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- fp_tools_bio-0.1.4/PKG-INFO +202 -0
- fp_tools_bio-0.1.4/README.md +164 -0
- fp_tools_bio-0.1.4/pyproject.toml +115 -0
- fp_tools_bio-0.1.4/setup.cfg +4 -0
- fp_tools_bio-0.1.4/setup.py +21 -0
- fp_tools_bio-0.1.4/src/fp_tools/__init__.py +3 -0
- fp_tools_bio-0.1.4/src/fp_tools/cli.py +8 -0
- fp_tools_bio-0.1.4/src/fp_tools/cli_batch.py +155 -0
- fp_tools_bio-0.1.4/src/fp_tools/cli_gui.py +96 -0
- fp_tools_bio-0.1.4/src/fp_tools/cli_plotaggregate.py +9 -0
- fp_tools_bio-0.1.4/src/fp_tools/cli_scorebigwig.py +8 -0
- fp_tools_bio-0.1.4/src/fp_tools/gui_app.py +880 -0
- fp_tools_bio-0.1.4/src/fp_tools/gui_config.py +256 -0
- fp_tools_bio-0.1.4/src/fp_tools/gui_forms.py +13 -0
- fp_tools_bio-0.1.4/src/fp_tools/gui_jobs.py +119 -0
- fp_tools_bio-0.1.4/src/fp_tools/parsers.py +587 -0
- fp_tools_bio-0.1.4/src/fp_tools/tools/__init__.py +1 -0
- fp_tools_bio-0.1.4/src/fp_tools/tools/atacorrect.py +506 -0
- fp_tools_bio-0.1.4/src/fp_tools/tools/atacorrect_functions.py +516 -0
- fp_tools_bio-0.1.4/src/fp_tools/tools/bindetect.py +715 -0
- fp_tools_bio-0.1.4/src/fp_tools/tools/bindetect_functions.py +924 -0
- fp_tools_bio-0.1.4/src/fp_tools/tools/bindetect_skew_report.py +544 -0
- fp_tools_bio-0.1.4/src/fp_tools/tools/plot_aggregate.py +459 -0
- fp_tools_bio-0.1.4/src/fp_tools/tools/score_bigwig.py +250 -0
- fp_tools_bio-0.1.4/src/fp_tools/utils/__init__.py +1 -0
- fp_tools_bio-0.1.4/src/fp_tools/utils/logger.py +184 -0
- fp_tools_bio-0.1.4/src/fp_tools/utils/motifs.py +794 -0
- fp_tools_bio-0.1.4/src/fp_tools/utils/ngs.c +17917 -0
- fp_tools_bio-0.1.4/src/fp_tools/utils/ngs.pyx +199 -0
- fp_tools_bio-0.1.4/src/fp_tools/utils/plotting_style.py +60 -0
- fp_tools_bio-0.1.4/src/fp_tools/utils/regions.py +758 -0
- fp_tools_bio-0.1.4/src/fp_tools/utils/sequences.c +21474 -0
- fp_tools_bio-0.1.4/src/fp_tools/utils/sequences.pyx +443 -0
- fp_tools_bio-0.1.4/src/fp_tools/utils/signals.c +16791 -0
- fp_tools_bio-0.1.4/src/fp_tools/utils/signals.pyx +282 -0
- fp_tools_bio-0.1.4/src/fp_tools/utils/utilities.py +618 -0
- fp_tools_bio-0.1.4/src/fp_tools_bio.egg-info/PKG-INFO +202 -0
- fp_tools_bio-0.1.4/src/fp_tools_bio.egg-info/SOURCES.txt +40 -0
- fp_tools_bio-0.1.4/src/fp_tools_bio.egg-info/dependency_links.txt +1 -0
- fp_tools_bio-0.1.4/src/fp_tools_bio.egg-info/entry_points.txt +8 -0
- fp_tools_bio-0.1.4/src/fp_tools_bio.egg-info/requires.txt +18 -0
- fp_tools_bio-0.1.4/src/fp_tools_bio.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: fp-tools-bio
|
|
3
|
+
Version: 0.1.4
|
|
4
|
+
Summary: Standalone footprint tools with vendored Cython internals
|
|
5
|
+
Author-email: Yaoxiang Li <liyaoxiang@outlook.com>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/lzyacht/fp-tools
|
|
8
|
+
Project-URL: Repository, https://github.com/lzyacht/fp-tools
|
|
9
|
+
Project-URL: Issues, https://github.com/lzyacht/fp-tools/issues
|
|
10
|
+
Keywords: ATAC-seq,footprinting,motif,chromatin,bioinformatics
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Intended Audience :: Science/Research
|
|
13
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
+
Classifier: Programming Language :: Cython
|
|
17
|
+
Classifier: Topic :: Scientific/Engineering :: Bio-Informatics
|
|
18
|
+
Requires-Python: >=3.12
|
|
19
|
+
Description-Content-Type: text/markdown
|
|
20
|
+
Requires-Dist: numpy<3.0,>=1.22
|
|
21
|
+
Requires-Dist: scipy<2.0,>=1.16
|
|
22
|
+
Requires-Dist: pysam<0.24.0,>=0.23.3
|
|
23
|
+
Requires-Dist: pyBigWig<0.4.0,>=0.3.24
|
|
24
|
+
Requires-Dist: matplotlib<4.0,>=3.10
|
|
25
|
+
Requires-Dist: pandas<3.0,>=2.3.3
|
|
26
|
+
Requires-Dist: seaborn<0.14.0,>=0.13.2
|
|
27
|
+
Requires-Dist: pybedtools<0.13,>=0.12
|
|
28
|
+
Requires-Dist: scikit-learn<2.0,>=1.5
|
|
29
|
+
Requires-Dist: tqdm<5.0,>=4.66
|
|
30
|
+
Requires-Dist: kneed<0.9.0,>=0.8.5
|
|
31
|
+
Requires-Dist: adjustText<2.0.0,>=1.3.0
|
|
32
|
+
Requires-Dist: moods-python<2.0.0.0,>=1.9.4.1
|
|
33
|
+
Requires-Dist: biopython<2.0,>=1.85
|
|
34
|
+
Requires-Dist: logomaker<0.9.0,>=0.8.7
|
|
35
|
+
Requires-Dist: xlsxwriter<4.0.0,>=3.2.9
|
|
36
|
+
Requires-Dist: PyYAML<7.0,>=6.0
|
|
37
|
+
Requires-Dist: streamlit<2.0,>=1.44
|
|
38
|
+
|
|
39
|
+
# fp-tools
|
|
40
|
+
|
|
41
|
+
`fp-tools` is a standalone footprinting package built around four packaged commands:
|
|
42
|
+
|
|
43
|
+
- `ATACorrect`
|
|
44
|
+
- `FootprintScores`
|
|
45
|
+
- `BINDetect`
|
|
46
|
+
- `PlotAggregate`
|
|
47
|
+
|
|
48
|
+
It also includes:
|
|
49
|
+
|
|
50
|
+
- `fp-tools-run` for optional YAML-driven batch execution
|
|
51
|
+
- `fp-tools-gui` for a browser-based per-user GUI wrapper
|
|
52
|
+
|
|
53
|
+
## Build
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
./scripts/build_release.sh
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Release artifacts are written to `dist/`.
|
|
60
|
+
|
|
61
|
+
## Install
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
pip install fp-tools-bio
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Verify
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
ATACorrect --help
|
|
71
|
+
FootprintScores --help
|
|
72
|
+
BINDetect --help
|
|
73
|
+
PlotAggregate --help
|
|
74
|
+
fp-tools-run --help
|
|
75
|
+
fp-tools-gui --help
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Minimal Workflow
|
|
79
|
+
|
|
80
|
+
### 1. ATACorrect
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
ATACorrect \
|
|
84
|
+
--bam test_data/Bcell.bam \
|
|
85
|
+
--genome test_data/genome.fa.gz \
|
|
86
|
+
--peaks test_data/merged_peaks.bed \
|
|
87
|
+
--blacklist test_data/blacklist.bed \
|
|
88
|
+
--outdir examples/atacorrect/ATACorrect_test2 \
|
|
89
|
+
--cores 1
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### 2. FootprintScores
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
FootprintScores \
|
|
96
|
+
--signal examples/atacorrect/ATACorrect_test2/Bcell_corrected.bw \
|
|
97
|
+
--regions test_data/merged_peaks.bed \
|
|
98
|
+
--output examples/scorebigwig/ScoreBigwig_test2/Bcell_footprints.bw \
|
|
99
|
+
--cores 1
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### 3. BINDetect
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
BINDetect \
|
|
106
|
+
--motifs test_data/motifs.jaspar \
|
|
107
|
+
--signals test_data/Bcell_footprints.bw test_data/Tcell_footprints.bw \
|
|
108
|
+
--genome test_data/genome.fa.gz \
|
|
109
|
+
--peaks test_data/merged_peaks_annotated.bed \
|
|
110
|
+
--peak-header test_data/merged_peaks_annotated_header.txt \
|
|
111
|
+
--outdir examples/bindetect/BINDetect_output_htmlfix_014 \
|
|
112
|
+
--cond-names Bcell Tcell \
|
|
113
|
+
--cores 1
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### 4. PlotAggregate
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
PlotAggregate \
|
|
120
|
+
--TFBS test_data/IRF1_all.bed \
|
|
121
|
+
--signals test_data/Bcell_corrected.bw \
|
|
122
|
+
--output examples/reports/plotaggregate_control_mode_test.pdf \
|
|
123
|
+
--output_aggregated_scores examples/reports/plotaggregate_control_mode_test_scores.csv
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## GUI
|
|
127
|
+
|
|
128
|
+
Start the GUI on a Linux server:
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
fp-tools-gui --host 0.0.0.0 --run-dir examples/gui_runs
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
If `--port` is omitted, the launcher picks a free port automatically and prints the exact URL.
|
|
135
|
+
|
|
136
|
+
You can also use a fixed port:
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
fp-tools-gui --host 0.0.0.0 --port 8891 --run-dir examples/gui_runs
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
The GUI supports:
|
|
143
|
+
|
|
144
|
+
- direct form-driven runs
|
|
145
|
+
- loading YAML configs
|
|
146
|
+
- saving YAML configs
|
|
147
|
+
- sample-list batch runs
|
|
148
|
+
- BINDetect comparison-list batch runs
|
|
149
|
+
- basic pre-launch config validation
|
|
150
|
+
- run-history inspection with detected output paths
|
|
151
|
+
|
|
152
|
+
GUI run metadata and logs are written under:
|
|
153
|
+
|
|
154
|
+
- `examples/gui_runs/`
|
|
155
|
+
|
|
156
|
+
Example GUI output files are written under:
|
|
157
|
+
|
|
158
|
+
- `examples/gui_demo_outputs/`
|
|
159
|
+
|
|
160
|
+
Ready-to-load GUI YAML examples are in:
|
|
161
|
+
|
|
162
|
+
- `examples/gui_configs/`
|
|
163
|
+
|
|
164
|
+
## YAML Runner
|
|
165
|
+
|
|
166
|
+
Direct CLI usage remains primary and does not require YAML.
|
|
167
|
+
|
|
168
|
+
YAML is an optional extra path for:
|
|
169
|
+
|
|
170
|
+
- GUI interoperability
|
|
171
|
+
- saved run configs
|
|
172
|
+
- batch execution
|
|
173
|
+
|
|
174
|
+
Run a config file with:
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
fp-tools-run --config examples/gui_configs/plotaggregate_single.yml
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
## Reference Examples
|
|
181
|
+
|
|
182
|
+
Core validated example outputs:
|
|
183
|
+
|
|
184
|
+
- `examples/atacorrect/ATACorrect_test_rc014`
|
|
185
|
+
- `examples/scorebigwig/ScoreBigwig_test_rc014`
|
|
186
|
+
- `examples/bindetect/BINDetect_output_rc014`
|
|
187
|
+
- `examples/reports/plotaggregate_rc014.pdf`
|
|
188
|
+
|
|
189
|
+
Additional validated examples:
|
|
190
|
+
|
|
191
|
+
- `examples/bindetect/BINDetect_output_synthetic_replicates_demo`
|
|
192
|
+
- `examples/bindetect/BINDetect_output_jaspar2026_manualcheck`
|
|
193
|
+
- `examples/bindetect/BINDetect_output_htmlfix_014`
|
|
194
|
+
- `examples/reports/plotaggregate_control_mode_test.pdf`
|
|
195
|
+
- `examples/reports/plotaggregate_dirinput_test.pdf`
|
|
196
|
+
- `examples/reports/plotaggregate_signals_export_test.pdf`
|
|
197
|
+
|
|
198
|
+
## Notes
|
|
199
|
+
|
|
200
|
+
- `fp-tools` builds on ideas and workflows from TOBIAS.
|
|
201
|
+
- The direct packaged commands remain the primary interface.
|
|
202
|
+
- The GUI is an isolated wrapper layer and does not replace the core CLI.
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
# fp-tools
|
|
2
|
+
|
|
3
|
+
`fp-tools` is a standalone footprinting package built around four packaged commands:
|
|
4
|
+
|
|
5
|
+
- `ATACorrect`
|
|
6
|
+
- `FootprintScores`
|
|
7
|
+
- `BINDetect`
|
|
8
|
+
- `PlotAggregate`
|
|
9
|
+
|
|
10
|
+
It also includes:
|
|
11
|
+
|
|
12
|
+
- `fp-tools-run` for optional YAML-driven batch execution
|
|
13
|
+
- `fp-tools-gui` for a browser-based per-user GUI wrapper
|
|
14
|
+
|
|
15
|
+
## Build
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
./scripts/build_release.sh
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Release artifacts are written to `dist/`.
|
|
22
|
+
|
|
23
|
+
## Install
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
pip install fp-tools-bio
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Verify
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
ATACorrect --help
|
|
33
|
+
FootprintScores --help
|
|
34
|
+
BINDetect --help
|
|
35
|
+
PlotAggregate --help
|
|
36
|
+
fp-tools-run --help
|
|
37
|
+
fp-tools-gui --help
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Minimal Workflow
|
|
41
|
+
|
|
42
|
+
### 1. ATACorrect
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
ATACorrect \
|
|
46
|
+
--bam test_data/Bcell.bam \
|
|
47
|
+
--genome test_data/genome.fa.gz \
|
|
48
|
+
--peaks test_data/merged_peaks.bed \
|
|
49
|
+
--blacklist test_data/blacklist.bed \
|
|
50
|
+
--outdir examples/atacorrect/ATACorrect_test2 \
|
|
51
|
+
--cores 1
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### 2. FootprintScores
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
FootprintScores \
|
|
58
|
+
--signal examples/atacorrect/ATACorrect_test2/Bcell_corrected.bw \
|
|
59
|
+
--regions test_data/merged_peaks.bed \
|
|
60
|
+
--output examples/scorebigwig/ScoreBigwig_test2/Bcell_footprints.bw \
|
|
61
|
+
--cores 1
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### 3. BINDetect
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
BINDetect \
|
|
68
|
+
--motifs test_data/motifs.jaspar \
|
|
69
|
+
--signals test_data/Bcell_footprints.bw test_data/Tcell_footprints.bw \
|
|
70
|
+
--genome test_data/genome.fa.gz \
|
|
71
|
+
--peaks test_data/merged_peaks_annotated.bed \
|
|
72
|
+
--peak-header test_data/merged_peaks_annotated_header.txt \
|
|
73
|
+
--outdir examples/bindetect/BINDetect_output_htmlfix_014 \
|
|
74
|
+
--cond-names Bcell Tcell \
|
|
75
|
+
--cores 1
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### 4. PlotAggregate
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
PlotAggregate \
|
|
82
|
+
--TFBS test_data/IRF1_all.bed \
|
|
83
|
+
--signals test_data/Bcell_corrected.bw \
|
|
84
|
+
--output examples/reports/plotaggregate_control_mode_test.pdf \
|
|
85
|
+
--output_aggregated_scores examples/reports/plotaggregate_control_mode_test_scores.csv
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## GUI
|
|
89
|
+
|
|
90
|
+
Start the GUI on a Linux server:
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
fp-tools-gui --host 0.0.0.0 --run-dir examples/gui_runs
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
If `--port` is omitted, the launcher picks a free port automatically and prints the exact URL.
|
|
97
|
+
|
|
98
|
+
You can also use a fixed port:
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
fp-tools-gui --host 0.0.0.0 --port 8891 --run-dir examples/gui_runs
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
The GUI supports:
|
|
105
|
+
|
|
106
|
+
- direct form-driven runs
|
|
107
|
+
- loading YAML configs
|
|
108
|
+
- saving YAML configs
|
|
109
|
+
- sample-list batch runs
|
|
110
|
+
- BINDetect comparison-list batch runs
|
|
111
|
+
- basic pre-launch config validation
|
|
112
|
+
- run-history inspection with detected output paths
|
|
113
|
+
|
|
114
|
+
GUI run metadata and logs are written under:
|
|
115
|
+
|
|
116
|
+
- `examples/gui_runs/`
|
|
117
|
+
|
|
118
|
+
Example GUI output files are written under:
|
|
119
|
+
|
|
120
|
+
- `examples/gui_demo_outputs/`
|
|
121
|
+
|
|
122
|
+
Ready-to-load GUI YAML examples are in:
|
|
123
|
+
|
|
124
|
+
- `examples/gui_configs/`
|
|
125
|
+
|
|
126
|
+
## YAML Runner
|
|
127
|
+
|
|
128
|
+
Direct CLI usage remains primary and does not require YAML.
|
|
129
|
+
|
|
130
|
+
YAML is an optional extra path for:
|
|
131
|
+
|
|
132
|
+
- GUI interoperability
|
|
133
|
+
- saved run configs
|
|
134
|
+
- batch execution
|
|
135
|
+
|
|
136
|
+
Run a config file with:
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
fp-tools-run --config examples/gui_configs/plotaggregate_single.yml
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
## Reference Examples
|
|
143
|
+
|
|
144
|
+
Core validated example outputs:
|
|
145
|
+
|
|
146
|
+
- `examples/atacorrect/ATACorrect_test_rc014`
|
|
147
|
+
- `examples/scorebigwig/ScoreBigwig_test_rc014`
|
|
148
|
+
- `examples/bindetect/BINDetect_output_rc014`
|
|
149
|
+
- `examples/reports/plotaggregate_rc014.pdf`
|
|
150
|
+
|
|
151
|
+
Additional validated examples:
|
|
152
|
+
|
|
153
|
+
- `examples/bindetect/BINDetect_output_synthetic_replicates_demo`
|
|
154
|
+
- `examples/bindetect/BINDetect_output_jaspar2026_manualcheck`
|
|
155
|
+
- `examples/bindetect/BINDetect_output_htmlfix_014`
|
|
156
|
+
- `examples/reports/plotaggregate_control_mode_test.pdf`
|
|
157
|
+
- `examples/reports/plotaggregate_dirinput_test.pdf`
|
|
158
|
+
- `examples/reports/plotaggregate_signals_export_test.pdf`
|
|
159
|
+
|
|
160
|
+
## Notes
|
|
161
|
+
|
|
162
|
+
- `fp-tools` builds on ideas and workflows from TOBIAS.
|
|
163
|
+
- The direct packaged commands remain the primary interface.
|
|
164
|
+
- The GUI is an isolated wrapper layer and does not replace the core CLI.
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
# setuptools does the build; Cython & NumPy headers are available at build time
|
|
3
|
+
requires = [
|
|
4
|
+
"setuptools>=68",
|
|
5
|
+
"wheel",
|
|
6
|
+
"Cython>=3.0",
|
|
7
|
+
"numpy>=1.22"
|
|
8
|
+
]
|
|
9
|
+
build-backend = "setuptools.build_meta"
|
|
10
|
+
|
|
11
|
+
[project]
|
|
12
|
+
name = "fp-tools-bio"
|
|
13
|
+
version = "0.1.4"
|
|
14
|
+
description = "Standalone footprint tools with vendored Cython internals"
|
|
15
|
+
readme = "README.md"
|
|
16
|
+
license = "MIT"
|
|
17
|
+
authors = [{ name = "Yaoxiang Li", email = "liyaoxiang@outlook.com" }]
|
|
18
|
+
requires-python = ">=3.12"
|
|
19
|
+
keywords = ["ATAC-seq", "footprinting", "motif", "chromatin", "bioinformatics"]
|
|
20
|
+
classifiers = [
|
|
21
|
+
"Development Status :: 4 - Beta",
|
|
22
|
+
"Intended Audience :: Science/Research",
|
|
23
|
+
"Operating System :: POSIX :: Linux",
|
|
24
|
+
"Programming Language :: Python :: 3",
|
|
25
|
+
"Programming Language :: Python :: 3.12",
|
|
26
|
+
"Programming Language :: Cython",
|
|
27
|
+
"Topic :: Scientific/Engineering :: Bio-Informatics",
|
|
28
|
+
]
|
|
29
|
+
|
|
30
|
+
# Runtime deps (unified here so pip/wheel installs work without Poetry)
|
|
31
|
+
dependencies = [
|
|
32
|
+
"numpy>=1.22,<3.0",
|
|
33
|
+
"scipy>=1.16,<2.0",
|
|
34
|
+
"pysam>=0.23.3,<0.24.0",
|
|
35
|
+
"pyBigWig>=0.3.24,<0.4.0",
|
|
36
|
+
"matplotlib>=3.10,<4.0",
|
|
37
|
+
"pandas>=2.3.3,<3.0",
|
|
38
|
+
"seaborn>=0.13.2,<0.14.0",
|
|
39
|
+
"pybedtools>=0.12,<0.13",
|
|
40
|
+
"scikit-learn>=1.5,<2.0",
|
|
41
|
+
"tqdm>=4.66,<5.0",
|
|
42
|
+
"kneed>=0.8.5,<0.9.0",
|
|
43
|
+
"adjustText>=1.3.0,<2.0.0",
|
|
44
|
+
"moods-python>=1.9.4.1,<2.0.0.0",
|
|
45
|
+
"biopython>=1.85,<2.0",
|
|
46
|
+
"logomaker>=0.8.7,<0.9.0",
|
|
47
|
+
"xlsxwriter>=3.2.9,<4.0.0",
|
|
48
|
+
"PyYAML>=6.0,<7.0",
|
|
49
|
+
"streamlit>=1.44,<2.0"
|
|
50
|
+
]
|
|
51
|
+
|
|
52
|
+
[project.urls]
|
|
53
|
+
Homepage = "https://github.com/lzyacht/fp-tools"
|
|
54
|
+
Repository = "https://github.com/lzyacht/fp-tools"
|
|
55
|
+
Issues = "https://github.com/lzyacht/fp-tools/issues"
|
|
56
|
+
|
|
57
|
+
[project.scripts]
|
|
58
|
+
ATACorrect = "fp_tools.cli:main"
|
|
59
|
+
FootprintScores = "fp_tools.cli_scorebigwig:main"
|
|
60
|
+
ScoreBigwig = "fp_tools.cli_scorebigwig:main"
|
|
61
|
+
BINDetect = "fp_tools.tools.bindetect:run_cli"
|
|
62
|
+
PlotAggregate = "fp_tools.cli_plotaggregate:main"
|
|
63
|
+
fp-tools-run = "fp_tools.cli_batch:main"
|
|
64
|
+
fp-tools-gui = "fp_tools.cli_gui:main"
|
|
65
|
+
|
|
66
|
+
[tool.setuptools]
|
|
67
|
+
package-dir = { "" = "src" }
|
|
68
|
+
include-package-data = true
|
|
69
|
+
|
|
70
|
+
[tool.setuptools.packages.find]
|
|
71
|
+
where = ["src"]
|
|
72
|
+
include = ["fp_tools*"]
|
|
73
|
+
|
|
74
|
+
# ship .pyx/.pxd in sdists so downstream builds can compile
|
|
75
|
+
[tool.setuptools.package-data]
|
|
76
|
+
"fp_tools.utils" = ["*.pyx", "*.pxd"]
|
|
77
|
+
|
|
78
|
+
# --- Poetry mirror of the important bits so `poetry build` works too ---
|
|
79
|
+
[tool.poetry]
|
|
80
|
+
name = "fp-tools-bio"
|
|
81
|
+
version = "0.1.4"
|
|
82
|
+
description = "Standalone footprint tools with vendored Cython internals"
|
|
83
|
+
authors = ["Yaoxiang Li <liyaoxiang@outlook.com>"]
|
|
84
|
+
readme = "README.md"
|
|
85
|
+
packages = [{ include = "fp_tools", from = "src" }]
|
|
86
|
+
|
|
87
|
+
[tool.poetry.dependencies]
|
|
88
|
+
python = ">=3.12,<4.0"
|
|
89
|
+
numpy = ">=1.22,<3.0"
|
|
90
|
+
scipy = ">=1.16,<2.0"
|
|
91
|
+
pysam = ">=0.23.3,<0.24.0"
|
|
92
|
+
pybigwig = ">=0.3.24,<0.4.0"
|
|
93
|
+
matplotlib = ">=3.10,<4.0"
|
|
94
|
+
pandas = ">=2.3.3,<3.0"
|
|
95
|
+
seaborn = ">=0.13.2,<0.14.0"
|
|
96
|
+
pybedtools = ">=0.12,<0.13"
|
|
97
|
+
scikit-learn = ">=1.5,<2.0"
|
|
98
|
+
tqdm = ">=4.66,<5.0"
|
|
99
|
+
kneed = ">=0.8.5,<0.9.0"
|
|
100
|
+
adjusttext = ">=1.3.0,<2.0.0"
|
|
101
|
+
moods-python = ">=1.9.4.1,<2.0.0.0"
|
|
102
|
+
biopython = ">=1.85,<2.0"
|
|
103
|
+
logomaker = ">=0.8.7,<0.9.0"
|
|
104
|
+
xlsxwriter = ">=3.2.9,<4.0.0"
|
|
105
|
+
pyyaml = ">=6.0,<7.0"
|
|
106
|
+
streamlit = ">=1.44,<2.0"
|
|
107
|
+
|
|
108
|
+
[tool.poetry.scripts]
|
|
109
|
+
ATACorrect = "fp_tools.cli:main"
|
|
110
|
+
FootprintScores = "fp_tools.cli_scorebigwig:main"
|
|
111
|
+
ScoreBigwig = "fp_tools.cli_scorebigwig:main"
|
|
112
|
+
BINDetect = "fp_tools.tools.bindetect:run_cli"
|
|
113
|
+
PlotAggregate = "fp_tools.cli_plotaggregate:main"
|
|
114
|
+
fp-tools-run = "fp_tools.cli_batch:main"
|
|
115
|
+
fp-tools-gui = "fp_tools.cli_gui:main"
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# setup.py
|
|
2
|
+
from setuptools import setup, Extension
|
|
3
|
+
from Cython.Build import cythonize
|
|
4
|
+
import numpy, pathlib
|
|
5
|
+
|
|
6
|
+
ext_modules = [
|
|
7
|
+
Extension("fp_tools.utils.sequences", [str(pathlib.Path("src/fp_tools/utils/sequences.pyx"))],
|
|
8
|
+
include_dirs=[numpy.get_include()]),
|
|
9
|
+
Extension("fp_tools.utils.ngs", [str(pathlib.Path("src/fp_tools/utils/ngs.pyx"))],
|
|
10
|
+
include_dirs=[numpy.get_include()]),
|
|
11
|
+
Extension("fp_tools.utils.signals", [str(pathlib.Path("src/fp_tools/utils/signals.pyx"))],
|
|
12
|
+
include_dirs=[numpy.get_include()]),
|
|
13
|
+
]
|
|
14
|
+
|
|
15
|
+
setup(
|
|
16
|
+
ext_modules=cythonize(
|
|
17
|
+
ext_modules,
|
|
18
|
+
language_level="3",
|
|
19
|
+
compiler_directives={"boundscheck": False, "wraparound": False},
|
|
20
|
+
),
|
|
21
|
+
)
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
"""Optional YAML-driven batch/config runner for fp-tools.
|
|
2
|
+
|
|
3
|
+
Direct CLI usage remains primary. This module adds an extra path for:
|
|
4
|
+
- replaying GUI-saved configs
|
|
5
|
+
- running batch sample lists
|
|
6
|
+
- running batch BINDetect comparison lists
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
import argparse
|
|
12
|
+
import json
|
|
13
|
+
import os
|
|
14
|
+
import shutil
|
|
15
|
+
import subprocess
|
|
16
|
+
import sys
|
|
17
|
+
from datetime import datetime
|
|
18
|
+
from pathlib import Path
|
|
19
|
+
|
|
20
|
+
from fp_tools.gui_config import JobSpec, canonical_tool_name, dump_yaml_config, expand_jobs, load_yaml_config, normalize_config
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def main() -> None:
|
|
24
|
+
parser = argparse.ArgumentParser(description="Run fp-tools jobs from a YAML config file.")
|
|
25
|
+
parser.add_argument("--config", required=True, help="Path to YAML config.")
|
|
26
|
+
parser.add_argument("--run-root", default=None, help="Optional directory for run metadata/logs.")
|
|
27
|
+
parser.add_argument("--only", nargs="*", default=None, help="Optional tool filter, e.g. BINDetect.")
|
|
28
|
+
parser.add_argument("--dry-run", action="store_true", help="Print expanded commands without running.")
|
|
29
|
+
parser.add_argument("--list-jobs", action="store_true", help="List expanded jobs and exit.")
|
|
30
|
+
parser.add_argument("--fail-fast", action="store_true", help="Stop at first failed job.")
|
|
31
|
+
args = parser.parse_args()
|
|
32
|
+
|
|
33
|
+
only_tools = {canonical_tool_name(tool_name) for tool_name in (args.only or [])}
|
|
34
|
+
exit_code = run_config_file(
|
|
35
|
+
args.config,
|
|
36
|
+
run_root=args.run_root,
|
|
37
|
+
only_tools=only_tools or None,
|
|
38
|
+
dry_run=args.dry_run,
|
|
39
|
+
list_jobs=args.list_jobs,
|
|
40
|
+
fail_fast=args.fail_fast,
|
|
41
|
+
)
|
|
42
|
+
raise SystemExit(exit_code)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def run_config_file(
|
|
46
|
+
config_path: str | os.PathLike[str],
|
|
47
|
+
run_root: str | os.PathLike[str] | None = None,
|
|
48
|
+
only_tools: set[str] | None = None,
|
|
49
|
+
dry_run: bool = False,
|
|
50
|
+
list_jobs: bool = False,
|
|
51
|
+
fail_fast: bool = False,
|
|
52
|
+
) -> int:
|
|
53
|
+
config = normalize_config(load_yaml_config(config_path))
|
|
54
|
+
jobs = expand_jobs(config, only_tools=only_tools)
|
|
55
|
+
if not jobs:
|
|
56
|
+
print("No jobs matched the current config/filter.", file=sys.stderr)
|
|
57
|
+
return 1
|
|
58
|
+
|
|
59
|
+
if list_jobs or dry_run:
|
|
60
|
+
for job in jobs:
|
|
61
|
+
print(f"[{job.tool}] {job.job_id}: {' '.join(job.command)}")
|
|
62
|
+
if dry_run or list_jobs:
|
|
63
|
+
return 0
|
|
64
|
+
|
|
65
|
+
root = Path(run_root or config.get("run_root") or _default_run_root()).expanduser()
|
|
66
|
+
root.mkdir(parents=True, exist_ok=True)
|
|
67
|
+
|
|
68
|
+
batch_index = root / "batch_index.tsv"
|
|
69
|
+
with batch_index.open("w", encoding="utf-8") as handle:
|
|
70
|
+
handle.write("job_id\ttool\tstatus\texit_code\trun_dir\n")
|
|
71
|
+
|
|
72
|
+
exit_code = 0
|
|
73
|
+
for job in jobs:
|
|
74
|
+
code = run_job(job, root)
|
|
75
|
+
status = "succeeded" if code == 0 else "failed"
|
|
76
|
+
with batch_index.open("a", encoding="utf-8") as handle:
|
|
77
|
+
handle.write(f"{job.job_id}\t{job.tool}\t{status}\t{code}\t{root / job.job_id}\n")
|
|
78
|
+
if code != 0:
|
|
79
|
+
exit_code = code
|
|
80
|
+
if fail_fast:
|
|
81
|
+
break
|
|
82
|
+
return exit_code
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def run_job(job: JobSpec, run_root: Path) -> int:
|
|
86
|
+
run_dir = run_root / job.job_id
|
|
87
|
+
run_dir.mkdir(parents=True, exist_ok=True)
|
|
88
|
+
|
|
89
|
+
dump_yaml_config(
|
|
90
|
+
{
|
|
91
|
+
"version": 1,
|
|
92
|
+
"run_mode": "single",
|
|
93
|
+
"defaults": {},
|
|
94
|
+
"samples" if job.section == "samples" else "comparisons": [
|
|
95
|
+
{"job_id": job.job_id, "tool": job.tool, **job.params}
|
|
96
|
+
],
|
|
97
|
+
"comparisons" if job.section == "samples" else "samples": [],
|
|
98
|
+
},
|
|
99
|
+
run_dir / "config.yml",
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
stdout_path = run_dir / "stdout.log"
|
|
103
|
+
stderr_path = run_dir / "stderr.log"
|
|
104
|
+
status_path = run_dir / "status.json"
|
|
105
|
+
cache_dir = run_dir / ".cache"
|
|
106
|
+
mpl_dir = run_dir / ".mplconfig"
|
|
107
|
+
cache_dir.mkdir(parents=True, exist_ok=True)
|
|
108
|
+
mpl_dir.mkdir(parents=True, exist_ok=True)
|
|
109
|
+
|
|
110
|
+
status = {
|
|
111
|
+
"tool": job.tool,
|
|
112
|
+
"job_id": job.job_id,
|
|
113
|
+
"status": "running",
|
|
114
|
+
"started_at": datetime.now().isoformat(timespec="seconds"),
|
|
115
|
+
"command": job.command,
|
|
116
|
+
}
|
|
117
|
+
status_path.write_text(json.dumps(status, indent=2), encoding="utf-8")
|
|
118
|
+
|
|
119
|
+
command = list(job.command)
|
|
120
|
+
command[0] = _resolve_executable(command[0])
|
|
121
|
+
status["command"] = command
|
|
122
|
+
status_path.write_text(json.dumps(status, indent=2), encoding="utf-8")
|
|
123
|
+
(run_dir / "command.txt").write_text(" ".join(command) + "\n", encoding="utf-8")
|
|
124
|
+
|
|
125
|
+
env = os.environ.copy()
|
|
126
|
+
env.setdefault("XDG_CACHE_HOME", str(cache_dir))
|
|
127
|
+
env.setdefault("MPLCONFIGDIR", str(mpl_dir))
|
|
128
|
+
|
|
129
|
+
with stdout_path.open("w", encoding="utf-8") as stdout_handle, stderr_path.open("w", encoding="utf-8") as stderr_handle:
|
|
130
|
+
process = subprocess.run(command, stdout=stdout_handle, stderr=stderr_handle, text=True, env=env)
|
|
131
|
+
|
|
132
|
+
status["status"] = "succeeded" if process.returncode == 0 else "failed"
|
|
133
|
+
status["finished_at"] = datetime.now().isoformat(timespec="seconds")
|
|
134
|
+
status["exit_code"] = process.returncode
|
|
135
|
+
status_path.write_text(json.dumps(status, indent=2), encoding="utf-8")
|
|
136
|
+
return process.returncode
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
def _default_run_root() -> Path:
|
|
140
|
+
stamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
|
141
|
+
return Path.cwd() / f"fp-tools-batch-{stamp}"
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
def _resolve_executable(name: str) -> str:
|
|
145
|
+
local = Path(sys.executable).parent / name
|
|
146
|
+
if local.exists():
|
|
147
|
+
return str(local)
|
|
148
|
+
found = shutil.which(name)
|
|
149
|
+
if found:
|
|
150
|
+
return found
|
|
151
|
+
return name
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
if __name__ == "__main__":
|
|
155
|
+
main()
|