def snp_histogram(reads, reference, templated_ops=None, templated=True):
    """
    Returns a histogram of the frequency of base-changes at each position.
    :param reads: a list of reads
    :param reference: the reference object
    :param templated_ops: a list of templated ops; if None, returns all SNPs, irrespective of the templated parameter
    :param templated: If templated_ops are specified, then templated=True will return the templated histogram, and
    False will return the non-templated histogram.
    :return: a list of floats
    """
    hist = [0] * len(reference.seq)
    for read in reads:
        for aln in read.alns:
            for op in aln.transform:
                # determines whether to include this op in histogram
                if templated_ops:
                    if (op in templated_ops) == templated:
                        include = True
                    else:
                        include = False
                else:
                    include = True

                # adds to histogram the frequency at each position, normalizing by the number of possible alignments of
                # the read.
                if op[1] in "S":
                    if include:
                        hist[op[0]] += 1 / len(reads) / len(read.alns)
                elif op[1] == "D":
                    for x in range(op[2]):
                        if include:
                            hist[op[0] + x] += 1 / len(reads) / len(read.alns)
                elif op[1] == "I":
                    if include:
                        hist[op[0]] += len(op[2]) / len(reads) / len(read.alns)
    return hist