ld_matrix.py 3.42 KB
Newer Older
Hanna  JULIENNE's avatar
Hanna JULIENNE committed
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
# coding: utf-8
"""
    Function set to compute LD correlation from a reference panel
    in predefined Region

    LD matrix are then transformed to the pandas sparse format
"""

import scipy as sc
import pandas as pd
import subprocess as sub
import pkg_resources
import numpy as np
import re


def launch_plink_ld(startpos, endpos, chr, reffile, folder):
    """
    launch plink linkage desiquilibrium correlation and save
    the ouput

    Args:
        startpos (int): position of the start of the window
        endpos (int): position of the end of the window
        chr (str): chromosome position
        reffile (str): reference panel file
        folder (str): output folder
    """
    bimref = reffile + ".bim"
    ref_panel = pd.read_csv(bimref, sep="\t", names=['chr', "nothing", 'pos', 'Ref_all', 'alt_all'], index_col = 1)

    ref_panel = ref_panel.loc[(ref_panel.pos > startpos) & (ref_panel.pos < endpos)]
    ref_panel.index.to_series().to_csv("./snp_list.txt", index=False)

    fo = "{0}/chr{1}_{2}_{3}".format(folder, chr, startpos, endpos)

    cmd = "plink --bfile {0} --r --ld-snp-list ./snp_list.txt --ld-window 50 --ld-window-kb 3000 --ld-window-r2 0.4 --chr {1} --out {2}".format(reffile, chr, fo)
    sub.check_output(cmd, shell=True)


def generate_sparse_matrix(plink_ld, ref_chr_df):
    """
    Extract correlation matrix from the plink correlation
    file generated by ld_matrix.launch_plink_ld
    read plink results create a sparse dataframe LD-matrix
    then save it to a zipped pickle

    Args:
        plink_ld (str): path to the plink correlation matrix file
        ref_chr_df (str):

    Returns:
        pandas.SparseDataFrame : Linkage desiquilibrium matrix
    """

    plink_ld = pd.read_csv(plink_ld, sep = "\s+")
    mat_ld = plink_ld.pivot(index='SNP_A', columns='SNP_B', values='R')
    un_index = mat_ld.index.union(mat_ld.columns)
    mat_ld = mat_ld.reindex(index=un_index, columns=un_index)
    mat_ld.fillna(0, inplace=True)

    sym = np.maximum(mat_ld.values,mat_ld.values.transpose())

    mat_ld = pd.DataFrame(sym, index=mat_ld.index, columns=mat_ld.columns)
    re_index = ref_chr_df.loc[mat_ld.index].sort_values(by="pos").index
    mat_ld = mat_ld.loc[re_index, re_index]
    mat_ld = mat_ld.to_sparse()
    return mat_ld

def generate_genome_matrices(region_files, reffolder, folder_output, suffix = ""):
    """
    go through region files and compute LD matrix for each transform and
    save the results in a pandas sparse dataframe

    Args:
        region_files (str) : region file containing beginning and end position
        reffolder (str) : folder of reference panel
        folder_output (str): folder to save plink LD correlation result files
    """
    regions = pd.read_csv(region_files)
    for reg in regions.iterrows():
        print(reg[0])
        # input reference panel file
        fi_ref = "{0}/{1}.{2}".format(reffolder, reg[1]['chr'], suffix)

        chr_int = re.search('([0-9]{1,2})', str(reg[1]['chr'])).group()
        # Compute the LD correlation with LD
        launch_plink_ld(reg[1]['start'], reg[1]['stop'], chr_int, fi_ref, folder_output)

        #fi_plink = "{0}/{1}_{2}_{3}.ld".format(folder_output, reg[1]['chr'], reg[1]['startpos'], reg[1]["endpos"])
        #fo_mat = "{0}/{1}_{2}_{3}.mat".format(folder_output, reg[1]['chr'], reg[1]['startpos'], reg[1]["endpos"])
        #transform plink output to a compressed generate_sparse_matrix
        #generate_sparse_matrix(fi_plink, fo_mat)