|
43 | 43 | """ |
44 | 44 |
|
45 | 45 | import ctypes |
| 46 | +import cooler |
46 | 47 | import multiprocessing as mp |
47 | 48 | import random |
48 | 49 | import warnings |
49 | 50 | from contextlib import closing |
50 | 51 |
|
51 | 52 | import numpy as np |
| 53 | +import pandas as pd |
52 | 54 |
|
53 | 55 | from . import polymer_analyses |
54 | 56 |
|
@@ -585,3 +587,49 @@ def monomerResolutionContactMapSubchains( |
585 | 587 | uniqueContacts=True, |
586 | 588 | nproc=n, |
587 | 589 | ) |
| 590 | + |
| 591 | + |
| 592 | +def coolify(contact_matrix, |
| 593 | + cool_uri, |
| 594 | + chrom_dict={}, |
| 595 | + binsize=2500, |
| 596 | + chunksize=10000000): |
| 597 | + """ |
| 598 | + Save a simulated contact map to .cool, and return corresponding Cooler |
| 599 | + |
| 600 | + Parameters |
| 601 | + ---------- |
| 602 | + contact_matrix : NxN int array |
| 603 | + Simulated contact map (in dense numpy.ndarray format) |
| 604 | + cool_uri : str |
| 605 | + Name of .cool file to be created (excluding extension) |
| 606 | + chrom_dict : dict |
| 607 | + Dictionary of chromosome lengths, in the form {'chr1':size1, ...} |
| 608 | + If unspecified, assumes the map spans a single chromosome |
| 609 | + binsize : int |
| 610 | + Map resolution in bp (i.e., genomic size of each simulated monomer) |
| 611 | + chunksize : int |
| 612 | + Number of pixels handled by each worker process |
| 613 | + |
| 614 | + Returns |
| 615 | + ------- |
| 616 | + Associated cooler.Cooler object |
| 617 | + """ |
| 618 | + |
| 619 | + nbins = contact_matrix.shape[0] |
| 620 | + |
| 621 | + chrom_dict = chrom_dict if chrom_dict else {'chr_sim': binsize*nbins} |
| 622 | + chrom_sizes = pd.Series(chrom_dict, name='length', dtype='int64') |
| 623 | + |
| 624 | + assert binsize*nbins == sum(chrom_sizes), "Chromosome sizes do not match map dimensions" |
| 625 | + |
| 626 | + bins = cooler.binnify(chrom_sizes, binsize) |
| 627 | + bins['weight'] = np.ones(nbins) * np.sqrt(2/nbins) |
| 628 | + |
| 629 | + pixels = cooler.create.ArrayLoader(bins, contact_matrix, chunksize=chunksize) |
| 630 | + |
| 631 | + cool_uri = f"{cool_uri}.{binsize}.cool" |
| 632 | + cooler.create_cooler(cool_uri, bins, pixels, ordered=True) |
| 633 | + |
| 634 | + return cooler.Cooler(cool_uri) |
| 635 | + |
0 commit comments