def outputSpikes(self, indices, tracks_map, groups,
                     output_method, spike_type,
                     min_cbin, width_cbin, max_cbin,
                     min_ibin, width_ibin, max_ibin,
                     min_sbin=1, width_sbin=1, max_sbin=1,
                     append=False):

        def makeHeader(tracks_map, groups, keep_columns=None):
            if keep_columns:
                header = keep_columns
            else:
                header = []
            header.extend(tracks_map[groups[0]])
            header.extend(tracks_map[groups[1]])

            return header

        if spike_type == "row":
            index = True
            # keep_columns = ["spike"]
            keep_columns = None

        elif spike_type == "cluster":
            index = False
            keep_columns = ["contig", "position"]

        header = makeHeader(tracks_map, groups, keep_columns=keep_columns)

        if output_method == "append":
            self.table = self.table.ix[:, header]
            self.table.to_csv(sys.stdout, index=index, header=True, sep="\t",
                              dtype={'position': int})
        else:
            sys.stdout.write("%s\t%s\n" % (
                "spike", "\t".join(map(str, header))))

        def getInitialChangeSize(key, width_ibin, min_ibin, width_cbin,
                                 min_cbin, width_s_bin, min_s_bin):
            initial_bin, change_bin, size_bin = key

            # initial and change values are the center of the bin
            initial = ((initial_bin*width_ibin) + min_ibin - (width_ibin*0.5))
            change = ((change_bin*width_cbin) + min_cbin - (width_cbin*0.5))
            size = ((size_bin*width_sbin) + min_sbin - 1)
            return initial, change, size

        def getInitialChange(key, width_ibin, min_ibin, width_cbin, min_cbin):
            initial_bin, change_bin = key

            # initial and change values are the center of the bin
            initial = ((initial_bin*width_ibin) + min_ibin - (width_ibin*0.5))
            change = ((change_bin*width_cbin) + min_cbin - (width_cbin*0.5))
            return initial, change

        n = 0

        if spike_type == "row":

            for key in indices:
                for pair in indices[key]:
                    initial, change = getInitialChange(
                        key, width_ibin, min_ibin, width_cbin, min_cbin)
                    row = ["_".join(map(str,
                                        ("spike-in", initial, change, n)))]
                    row.extend(self.table.ix[pair[0], tracks_map[groups[0]]])
                    row.extend(self.table.ix[pair[1], tracks_map[groups[1]]])
                    sys.stdout.write("%s\n" % "\t".join(map(str, row)))
                    n += 1

        elif spike_type == "cluster":
            for key in indices.keys():
                initial, change, size = getInitialChangeSize(
                    key, width_ibin, min_ibin, width_cbin,
                    min_cbin, width_sbin, min_sbin)
                for values in indices[key]:
                    (c1s, c1e, c2s, c2e, c1rs, c1re,
                     c2rs, c2re) = values
                    cluster_id = "_".join(
                        map(str, ("spike-in", initial, change,
                                  size, c1rs-c1s, n)))

                    temp_cluster_df = self.table.ix[c1s:c1e, keep_cols]
                    temp_cluster_df['contig'] = cluster_id
                    temp_cluster_swap = self.table.ix[
                        c2rs:c2re, tracks_map[groups[1]]]
                    temp_cluster_swap.set_index(self.table.ix[c1rs:c1re].index,
                                                drop=True,  inplace=True)
                    temp_cluster_df.ix[c1rs:c1re, tracks_map[
                        groups[1]]] = temp_cluster_swap
                    temp_cluster_df.to_csv(sys.stdout, index=index,
                                           header=False, sep="\t",
                                           dtype={'position': int})
                    n += 1


########################################################################
# these functions for spike-in should be re-written to work with the ###
# counts class                                                       ###
########################################################################
method to output spike-ins generated by shuffling rows
dataset/ETHPy150Open CGATOxford/cgat/CGAT/Counts.py/Counts.outputSpikes