File size: 11,860 Bytes
6d6b8ca
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4c2f064
 
6d6b8ca
 
 
4c2f064
6d6b8ca
4c2f064
6d6b8ca
4c2f064
6d6b8ca
4c2f064
6d6b8ca
4c2f064
 
 
 
6d6b8ca
4c2f064
6d6b8ca
4c2f064
 
 
 
6d6b8ca
4c2f064
6d6b8ca
4c2f064
 
 
 
 
 
 
 
 
 
 
 
 
 
6d6b8ca
4c2f064
 
 
 
 
 
 
 
 
6d6b8ca
4c2f064
 
 
 
6d6b8ca
 
 
4c2f064
 
 
6d6b8ca
 
4c2f064
6d6b8ca
4c2f064
 
6d6b8ca
 
 
4c2f064
6d6b8ca
 
 
4c2f064
 
6d6b8ca
 
 
4c2f064
 
 
6d6b8ca
4c2f064
 
 
 
6d6b8ca
 
4c2f064
 
 
 
 
6d6b8ca
 
4c2f064
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6d6b8ca
4c2f064
6d6b8ca
 
4c2f064
6d6b8ca
 
4c2f064
6d6b8ca
4c2f064
 
6d6b8ca
 
 
4c2f064
 
 
6d6b8ca
 
4c2f064
 
 
6d6b8ca
4c2f064
 
 
6d6b8ca
4c2f064
 
 
6d6b8ca
 
 
4c2f064
 
 
 
6d6b8ca
 
4c2f064
 
 
 
 
6d6b8ca
4c2f064
6d6b8ca
 
 
4c2f064
 
 
 
 
6d6b8ca
 
4c2f064
 
 
 
 
 
 
 
6d6b8ca
 
 
4c2f064
 
6d6b8ca
 
4c2f064
 
6d6b8ca
4c2f064
6d6b8ca
4c2f064
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6d6b8ca
 
4c2f064
 
 
 
 
 
 
 
 
6d6b8ca
 
4c2f064
 
 
 
 
 
 
6d6b8ca
 
4c2f064
 
 
 
 
 
 
 
 
 
6d6b8ca
 
4c2f064
 
 
 
6d6b8ca
4c2f064
 
 
 
6d6b8ca
 
4c2f064
 
 
6d6b8ca
 
4c2f064
 
 
 
 
6d6b8ca
 
4c2f064
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
---
license: mit
---

# ContextTAD

ContextTAD is a deep-learning TAD caller that learns boundary evidence from broader local Hi-C windows that capture TAD-scale structural context. Instead of treating boundary prediction as an isolated per-bin classification problem, ContextTAD uses a context-aware representation to produce left- and right-boundary tracks that are explicitly optimized for downstream TAD assembly.

Our github repo: https://github.com/ai4nucleome/ContextTAD

## Environment setup

Create a conda environment named `contexttad`.

```bash
conda create -n contexttad python=3.12 -y
conda activate contexttad
pip install -r requirements.txt
```


Additional external tools required by some evaluation/plotting scripts:

- `Rscript` (for structural protein enrichment)
- `coolpup.py` (for coolpup pileups)
- `pyGenomeTracks` (for genome track visualizations)


## Data preparation

The full processed dataset is too large to keep in the Git repository. The expected layout, array format, and preprocessing inputs are documented in [`0-data/README.md`](0-data/README.md).

**Note: Most processed resources are available from [Zenodo](https://doi.org/10.5281/zenodo.19062598). Raw `.mcool` files should be downloaded from the 4DN Data Portal.**

The two required data roots are:

```text
0-data/1_dp_train_infer_data/
0-data/2_eval_tads_data/
```

You may place them elsewhere and set:

```bash
export TAD_DATA_DIR=/path/to/1_dp_train_infer_data
export EVAL_DATA_ROOT=/path/to/2_eval_tads_data
```

### Main data sources

| Category | Cell line | Identifier or file | Source |
|---|---|---|---|
| Hi-C | GM12878 | `4DNFIXP4QG5B` and downsampled fractions | 4DN Data Portal |
| Hi-C | K562 | `4DNFI4DGNY7J` | 4DN Data Portal |
| Hi-C | IMR90 | `4DNFIJTOIGOI` | 4DN Data Portal |
| CTCF ChIP-seq | GM12878 | `ENCFF796WRU` | ENCODE |
| CTCF signal bigWig | GM12878 | `ENCFF232FCT` | ENCODE |
| CTCF ChIP-seq | K562 | `ENCFF901CBP` | ENCODE |
| CTCF ChIP-seq | IMR90 | `ENCFF203SRF` | ENCODE |
| CTCF ChIA-PET | GM12878 | `GSE72816` | GEO |
| CTCF ChIA-PET | K562 | `ENCFF001THV` | ENCODE |
| CTCF ChIA-PET | IMR90 | `ENCFF682YFU` | ENCODE |
| H3K27me3 ChIP-seq | GM12878 | `ENCFF039JOT` | ENCODE |
| H3K36me3 ChIP-seq | GM12878 | `ENCFF171MDW` | ENCODE |

The data sourcing follows the resources described by [RefHiC](https://www.nature.com/articles/s41467-022-35231-3).

## How to run (step by step)

The workflow is deliberately separated into data preparation, training,
inference/TAD construction, and evaluation. Run commands from the repository
root unless stated otherwise.

### Step 1: prepare training and inference arrays

Build the GM12878 windows after configuring the raw Hi-C and genomic-track
paths required by the preprocessing scripts:

```bash
python 1-prepare_data/step2_prepare_labels/scripts/prepare_data.py
```

The command will create the seven coverage directories, shared DP-refined labels,
and `window_list.json` under `TAD_DATA_DIR`. To process only a subset of the
coverage levels, use one of the following mutually exclusive options:

```bash
# Build only the 4000M arrays.
python 1-prepare_data/step2_prepare_labels/scripts/prepare_data.py --only-4000M

# Build all downsampled arrays while reusing an existing 4000M directory.
python 1-prepare_data/step2_prepare_labels/scripts/prepare_data.py --skip-4000M
```

Build K562 or IMR90 arrays for cross-cell inference with:

```bash
python 1-prepare_data/step1_process_data/scripts/prepare_othercell_inference_data.py \
  --mcool /path/to/cell_line.mcool::/resolutions/5000 \
  --out_data_dir "$TAD_DATA_DIR/other_celltypes/K562" \
  --coverage_tag K562
```

Here, `--mcool` selects the 5-kb matrix, `--out_data_dir` is the destination
for the processed windows, and `--coverage_tag` is the identifier written into
the generated metadata. Replace `K562` with `IMR90` for the second cell line.

### Step 2: train the base model

The base experiment uses O/E inputs, a diagonal radius of 50 bins, and random
coverage sampling for both training and validation.

```bash
bash 2-training/step1_train/scripts/run_train_base.sh \
  --gpu-ids 0 \
  --run-id train_base_$(date +%Y%m%d_%H%M%S) \
  --epochs 50 \
  --batch-size 16
```

`--gpu-ids` selects the devices exposed to Accelerate; use `--gpu-ids 0,1, ...` for
multi-GPU distributed training.

Outputs are written under:

```text
2-training/step1_train/outputs/<run_id>/
β”œβ”€β”€ logs/
β”œβ”€β”€ run_command.sh
└── train_outputs/
    β”œβ”€β”€ args.json
    β”œβ”€β”€ best_model.pt
    β”œβ”€β”€ final_model.pt
    β”œβ”€β”€ history.json
    └── checkpoints/
```

Inspect the training curves with:

```bash
tensorboard --logdir 2-training/step1_train/outputs
```

### Step 3: infer GM12878 TADs

Run the best checkpoint on all seven GM12878 coverage levels for held-out
chromosomes 15, 16, and 17:

```bash
bash 2-training/step2_infer_decode/scripts/run_infer_decode_gm12878.sh \
  --checkpoint /path/to/best_model.pt \
  --gpu-id 0 \
  --run-id infer_gm12878_$(date +%Y%m%d_%H%M%S)
```

`--checkpoint` accepts a checkpoint produced in Step 2 or downloaded from
Hugging Face. `--gpu-id` selects the inference device, and `--run-id` names the
output directory.

This stage writes chromosome-level boundary tracks, FDR-selected pair
candidates, postprocessing statistics, and final BED files under
`2-training/step2_infer_decode/outputs/<run_id>/`.

### Step 4: infer K562 and IMR90 TADs (optional)

Cross-cell inference uses the same checkpoint and decoder:

```bash
bash 2-training/step2_infer_decode/scripts/run_infer_decode_othercell.sh \
  --checkpoint /path/to/best_model.pt \
  --gpu-id 0 \
  --run-id infer_othercell_$(date +%Y%m%d_%H%M%S) \
  --data-root "$OTHERCELL_DATA_ROOT"
```

`--data-root` must contain the processed `K562/` and `IMR90/` array
directories. If omitted, the script uses the default location documented in
`0-data/README.md`.

### Step 5: evaluate the predictions

Evaluate the main GM12878 and cross-cell results against the reference callers:

```bash
bash 3-evaluation/step1_main_results_vs_tools/scripts/run_main_results.sh \
  --gm12878-beds /path/to/gm12878_beds \
  --othercell-beds /path/to/othercell_beds \
  --run-id main_results_$(date +%Y%m%d_%H%M%S) \
  --run-coolpup \
  --run-histone
```

`--gm12878-beds` refers to the seven-coverage output from Step 3, while
`--othercell-beds` refers to the K562/IMR90 output from Step 4.
`--run-histone` enables the histone permutation test, and
`--run-coolpup` enables aggregate pileup analysis. Omit either flag to skip that
optional experiment. TAD-size statistics are always computed because they only
require the 250M BED files.

Evaluate one ContextTAD variant on the core GM12878 experiments with:

```bash
bash 3-evaluation/step2_model_ablation_ours_only/scripts/run_model_ablation_eval.sh \
  --gm12878-beds /path/to/gm12878_beds \
  --run-id ablation_eval_$(date +%Y%m%d_%H%M%S)
```

This lightweight route runs exp1, exp3, exp4, and exp6 without requiring
other-cell data, histone tracks, or `.mcool` files.

### Evaluation experiment catalog

| Experiment | Analysis | Main manuscript use |
|---|---|---|
| `exp1_tadnum_ctcf_chiapet` | 250M CTCF ChIA-PET-supported L0/L1+ TAD counts | Figure 2b |
| `exp2_struct_protein` | CTCF, RAD21, and SMC3 boundary enrichment | Figure 2c |
| `exp3_tadb_left_ctcf_chipseq` | Left-boundary CTCF ChIP-seq support | Figure 2d |
| `exp4_tadb_right_ctcf_chipseq` | Right-boundary CTCF ChIP-seq support | Figure 2e |
| `exp5_coolpup` | Aggregate TAD pileups | Figure 5 |
| `exp6_tadnum_ctcf_chiapet_downsample` | Seven-coverage TAD counts and CTCF support | Figure 3 |
| `exp7_othercell_tadnum_ctcf_chiapet` | K562/IMR90 CTCF ChIA-PET support | Figure 4 |
| `exp8_othercell_both_ctcf_chipseq` | K562/IMR90 directional boundary support | Figure 4 |
| `exp9_tad_size` | 250M TAD-size distribution and median ranking | Figure 2a |
| `exp10_histone_modification` | H3K27me3/H3K36me3 contrast permutation test | Figure 2f |
| `exp11_pairscore_structure` | Pair-score quartile pileups, boundary insulation, and representative regions | Figure 6 |

Each directory under `3-evaluation/common/` contains its executable entry point
and a `DATA_REQUIREMENTS.md` file describing the required inputs and metric.

Run the two additional Figure 2 analyses independently with:

```bash
# TAD-size statistics (Figure 2a).
EVAL_DATA_ROOT=/path/to/2_eval_tads_data \
bash 3-evaluation/common/exp9_tad_size/run_exp9.sh

# Histone-modification contrast (Figure 2f).
EVAL_DATA_ROOT=/path/to/2_eval_tads_data \
RSCRIPT_BIN=/path/to/Rscript \
BEDTOOLS_BIN=/path/to/bedtools \
bash 3-evaluation/common/exp10_histone_modification/run_exp10.sh
```

`EVAL_DATA_ROOT` supplies the reference callers and benchmark tracks.
`RSCRIPT_BIN` and `BEDTOOLS_BIN` may be omitted when both commands are already
available on `PATH`.

Run the Figure 6 structural characterization independently because it requires
both final calls and the scored raw candidates from the same 4000M inference
run:

```bash
bash 3-evaluation/common/exp11_pairscore_structure/run_exp11.sh \
  --final-bed /path/to/GM12878_4000M_contexttad.bed \
  --raw-bed /path/to/ContextTAD_structure_4000M.bed \
  --mcool /path/to/GM12878_4000M.mcool \
  --chiapet /path/to/gm12878_ctcf_chiapet.bedpe \
  --ctcf /path/to/ENCFF232FCT_CTCF.bigWig \
  --h3k27 /path/to/ENCFF039JOT_H3K27me3.bigWig \
  --h3k36 /path/to/ENCFF171MDW_H3K36me3.bigWig \
  --output-dir /path/to/figure6_results \
  --cache-dir /path/to/figure6_cache
```

This produces the pair-score quartile pileups, left/right insulation profiles,
three representative genomic regions, and `fig6_final.{png,pdf}`. See
[`exp11_pairscore_structure/DATA_REQUIREMENTS.md`](3-evaluation/common/exp11_pairscore_structure/DATA_REQUIREMENTS.md)
for exact formats.

### Step 6: run the complete pipeline with one command

The shortest command trains on GPU 0, infers on GPU 0, and runs the core
GM12878 evaluation suite:

```bash
bash 4-fullpipeline/run_full_pipeline.sh \
  --train-gpus 0 \
  --infer-gpu 0
```

The omitted options use an automatically generated run ID, batch size 16, the
default Accelerate port, and the default 50-epoch schedule.

Run the complete suite, including K562/IMR90 inference, coolpup, TAD-size, and
histone-modification analyses, with:

```bash
bash 4-fullpipeline/run_full_pipeline.sh \
  --train-gpus 0 \
  --infer-gpu 0 \
  --run-id full_$(date +%Y%m%d_%H%M%S) \
  --train-epochs 50 \
  --batch-size 16 \
  --master-port 29600 \
  --all-exps
```

`--train-gpus` accepts one or more comma-separated devices, whereas
`--infer-gpu` selects one inference device. `--all-exps` enables other-cell
inference and the ten standard benchmark workflows. Figure 6 remains a
standalone analysis because it additionally consumes scored raw candidates and
genome-track files. The full-pipeline output contains symlinks to stage-specific
products; model weights remain only under `2-training/step1_train/outputs/`.

### Step 7: run ablation experiments

All ablations retain the base architecture and optimization settings unless
explicitly changed. Each wrapper accepts the same arguments as
`run_train_base.sh`:

```bash
# Observed contact matrix instead of O/E.
bash 2-training/step1_train/scripts/run_train_obs_input.sh \
  --gpu-ids 0 --run-id obs_input_run --epochs 50 --batch-size 16

# Pair objective removed.
bash 2-training/step1_train/scripts/run_train_no_pairloss.sh \
  --gpu-ids 0 --run-id no_pair_run --epochs 50 --batch-size 16

# Count objective removed.
bash 2-training/step1_train/scripts/run_train_no_count.sh \
  --gpu-ids 0 --run-id no_count_run --epochs 50 --batch-size 16

# Boundary BCE plus count objective, without pair loss.
bash 2-training/step1_train/scripts/run_train_boundary_count.sh \
  --gpu-ids 0 --run-id boundary_count_run --epochs 50 --batch-size 16
```