def density_over_range(lst, cpg_ranges):
    """
	Calculate CpG density over range (upstream, gene, downstream)
	lst = list of (chr,start,end, strand)
	cpg_ranges is returned by read_CpG_bed
	"""
    up_CpG_density = {}
    gene_CpG_density = {}
    down_CpG_density = {}
    for i in range(0, 101):
        up_CpG_density[i] = 0
        gene_CpG_density[i] = 0
        down_CpG_density[i] = 0
    for r1, r2, r3, strand in lst:
        if strand == '+':
            up_region = r1
            gene_region = r2
            down_region = r3
        elif strand == '-':
            up_region = r3
            gene_region = r2
            down_region = r1
        chrom = up_region[0]
        start = up_region[1]
        end = up_region[2]
        span = end - start
        if chrom not in cpg_ranges:
            continue
        tmp = cpg_ranges[chrom].find(start, end)
        for i in tmp:
            if strand == '+':
                CpG_to_origin = round((i.end - start) * 100 / span)
            elif strand == '-':
                CpG_to_origin = abs(round((i.end - end) * 100 / span))
            up_CpG_density[CpG_to_origin] += 1
        chrom = gene_region[0]
        start = gene_region[1]
        end = gene_region[2]
        span = end - start
        if chrom not in cpg_ranges:
            continue
        tmp = cpg_ranges[chrom].find(start, end)
        for i in tmp:
            if strand == '+':
                CpG_to_origin = round((i.end - start) * 100 / span)
            elif strand == '-':
                CpG_to_origin = abs(round((i.end - end) * 100 / span))
            gene_CpG_density[CpG_to_origin] += 1
        chrom = down_region[0]
        start = down_region[1]
        end = down_region[2]
        span = end - start
        if chrom not in cpg_ranges:
            continue
        tmp = cpg_ranges[chrom].find(start, end)
        for i in tmp:
            if strand == '+':
                CpG_to_origin = round((i.end - start) * 100 / span)
            elif strand == '-':
                CpG_to_origin = abs(round((i.end - end) * 100 / span))
            down_CpG_density[CpG_to_origin] += 1
    return up_CpG_density, gene_CpG_density, down_CpG_density
