def cluster(template_list, show=True, corr_thresh=<NUM_LIT>, allow_shift=False,<EOL>shift_len=<NUM_LIT:0>, save_corrmat=False, cores='<STR_LIT:all>', debug=<NUM_LIT:1>):
if cores == '<STR_LIT:all>':<EOL><INDENT>num_cores = cpu_count()<EOL><DEDENT>else:<EOL><INDENT>num_cores = cores<EOL><DEDENT>stream_list = [x[<NUM_LIT:0>] for x in template_list]<EOL>if debug >= <NUM_LIT:1>:<EOL><INDENT>print('<STR_LIT>' % num_cores)<EOL><DEDENT>dist_mat = distance_matrix(stream_list, allow_shift, shift_len,<EOL>cores=num_cores)<EOL>if save_corrmat:<EOL><INDENT>np.save('<STR_LIT>', dist_mat)<EOL>if debug >= <NUM_LIT:1>:<EOL><INDENT>print('<STR_LIT>')<EOL><DEDENT><DEDENT>dist_vec = squareform(dist_mat)<EOL>if debug >= <NUM_LIT:1>:<EOL><INDENT>print('<STR_LIT>')<EOL><DEDENT>Z = linkage(dist_vec)<EOL>if show:<EOL><INDENT>if debug >= <NUM_LIT:1>:<EOL><INDENT>print('<STR_LIT>')<EOL><DEDENT>dendrogram(Z, color_threshold=<NUM_LIT:1> - corr_thresh,<EOL>distance_sort='<STR_LIT>')<EOL>plt.show()<EOL><DEDENT>if debug >= <NUM_LIT:1>:<EOL><INDENT>print('<STR_LIT>')<EOL><DEDENT>indices = fcluster(Z, t=<NUM_LIT:1> - corr_thresh, criterion='<STR_LIT>')<EOL>group_ids = list(set(indices))  <EOL>if debug >= <NUM_LIT:1>:<EOL><INDENT>msg = '<STR_LIT:U+0020>'.join(['<STR_LIT>', str(len(group_ids)), '<STR_LIT>'])<EOL>print(msg)<EOL><DEDENT>indices = [(indices[i], i) for i in range(len(indices))]<EOL>indices.sort(key=lambda tup: tup[<NUM_LIT:0>])<EOL>groups = []<EOL>if debug >= <NUM_LIT:1>:<EOL><INDENT>print('<STR_LIT>')<EOL><DEDENT>for group_id in group_ids:<EOL><INDENT>group = []<EOL>for ind in indices:<EOL><INDENT>if ind[<NUM_LIT:0>] == group_id:<EOL><INDENT>group.append(template_list[ind[<NUM_LIT:1>]])<EOL><DEDENT>elif ind[<NUM_LIT:0>] > group_id:<EOL><INDENT>groups.append(group)<EOL>break<EOL><DEDENT><DEDENT><DEDENT>groups.append(group)<EOL>return groups<EOL>
Cluster template waveforms based on average correlations.

Function to take a set of templates and cluster them, will return groups
as lists of streams.  Clustering is done by computing the cross-channel
correlation sum of each stream in stream_list with every other stream in
the list.  :mod:`scipy.cluster.hierarchy` functions are then used to
compute the complete distance matrix, where distance is 1 minus the
normalised cross-correlation sum such that larger distances are less
similar events.  Groups are then created by clustering the distance matrix
at distances less than 1 - corr_thresh.

Will compute the distance matrix in parallel, using all available cores

:type template_list: list
:param template_list:
    List of tuples of the template (:class:`obspy.core.stream.Stream`)
    and the template id to compute clustering for
:type show: bool
:param show: plot linkage on screen if True, defaults to True
:type corr_thresh: float
:param corr_thresh: Cross-channel correlation threshold for grouping
:type allow_shift: bool
:param allow_shift:
    Whether to allow the templates to shift when correlating
:type shift_len: float
:param shift_len: How many seconds to allow the templates to shift
:type save_corrmat: bool
:param save_corrmat:
    If True will save the distance matrix to dist_mat.npy in the local
    directory.
:type cores: int
:param cores:
    number of cores to use when computing the distance matrix, defaults to
    'all' which will work out how many cpus are available and hog them.
:type debug: int
:param debug:
    Level of debugging from 1-5, higher is more output,
    currently only level 1 implemented.

:returns:
    List of groups. Each group is a list of
    :class:`obspy.core.stream.Stream` making up that group.