Finds the collections (clusters,chains) that exist in parsed_response.

        Modified:
            - self.collection_sizes: populated with a list of integers indicating
                the number of units belonging to each collection
            - self.collection_indices: populated with a list of strings indicating
                the indices of each element of each collection
            - self.collection_list: populated with a list lists, each list containing
                Unit objects belonging to each collection

        There are two types of collections currently implemented:
        - cluster: every entry in a cluster is sufficiently similar to every other entry
        - chain: every entry in a chain is sufficiently similar to adjacent entries

        Similarity between words is calculated using the compute_similarity_score method.
        Scores between words are then thresholded and binarized using empirically-derived
        thresholds (see: ???). Overlap of clusters is allowed (a word can be part of
        multiple clusters), but overlapping chains are not possible, as any two adjacent
        words with a lower-than-threshold similarity breaks the chain.  Clusters subsumed
        by other clusters are not counted. Singletons, i.e., clusters of size 1, are
        included in this analysis.


        .. todo: Find source for thresholding values.

def compute_collections(self):
        """ Finds the collections (clusters,chains) that exist in parsed_response.

        Modified:
            - self.collection_sizes: populated with a list of integers indicating
                the number of units belonging to each collection
            - self.collection_indices: populated with a list of strings indicating
                the indices of each element of each collection
            - self.collection_list: populated with a list lists, each list containing
                Unit objects belonging to each collection

        There are two types of collections currently implemented:
        - cluster: every entry in a cluster is sufficiently similar to every other entry
        - chain: every entry in a chain is sufficiently similar to adjacent entries

        Similarity between words is calculated using the compute_similarity_score method.
        Scores between words are then thresholded and binarized using empirically-derived
        thresholds (see: ???). Overlap of clusters is allowed (a word can be part of
        multiple clusters), but overlapping chains are not possible, as any two adjacent
        words with a lower-than-threshold similarity breaks the chain.  Clusters subsumed
        by other clusters are not counted. Singletons, i.e., clusters of size 1, are
        included in this analysis.


        .. todo: Find source for thresholding values.
        """
        if self.custom_threshold:
            self.similarity_threshold = self.custom_threshold
        elif self.type == "PHONETIC":
            if self.current_similarity_measure == "phone":
                phonetic_similarity_thresholds = {'a': 0.222222222222,
                                                  'b': 0.3,
                                                  'c': 0.2857142857134,
                                                  'd': 0.3,
                                                  'e': 0.25,
                                                  'f': 0.333333333333,
                                                  'g': 0.2857142857142857,
                                                  'h': 0.333333333333,
                                                  'i': 0.3,
                                                  'j': 0.3,
                                                  'k': 0.3,
                                                  'l': 0.333333333333,
                                                  'm': 0.333333333333,
                                                  'n': 0.2857142857142857,
                                                  'o': 0.222222222222,
                                                  'p': 0.2857142857134,
                                                  'q': 0.4285714285714286,
                                                  'r': 0.3,
                                                  's': 0.2857142857134,
                                                  't': 0.2857142857134,
                                                  'u': 0.3076923076923077,
                                                  'v': 0.333333333333,
                                                  'w': 0.333333333333,
                                                  'x': 0.2857142857134,
                                                  'y': 0.333333333333,
                                                  'z': 0.333333333333}
                self.similarity_threshold = phonetic_similarity_thresholds[self.letter]
            elif self.current_similarity_measure == "biphone":
                self.similarity_threshold = 1

        elif self.type == "SEMANTIC":
            if self.current_similarity_measure == "lsa":
                if self.category == 'animals':
                    thresholds = {'50': 0.229306542684, '51': 0.22594687203200001,
                                  '52': 0.22403235205800001, '53': 0.214750475853,
                                  '54': 0.210178113675, '55': 0.209214667474,
                                  '56': 0.204037629443, '57': 0.203801260742,
                                  '58': 0.203261303516, '59': 0.20351336452999999,
                                  '60': 0.19834361415999999, '61': 0.19752806852999999,
                                  '62': 0.191322450624, '63': 0.194312302459,
                                  '64': 0.188165419858, '65': 0.18464545450299999,
                                  '66': 0.18478136731399999, '67': 0.178950849271,
                                  '68': 0.17744175606199999, '69': 0.17639888996299999,
                                  '70': 0.17537403274400001, '71': 0.17235091169799999,
                                  '72': 0.17115875396499999, '73': 0.17262141635100001,
                                  '74': 0.16580303697500001, '75': 0.16416843492800001,
                                  '76': 0.166395146381, '77': 0.162961462955,
                                  '78': 0.161888890545, '79': 0.160416925579,
                                  '80': 0.157132807023, '81': 0.15965395155699999,
                                  '82': 0.155974588379, '83': 0.15606832182700001,
                                  '84': 0.14992240019899999, '85': 0.15186462595399999,
                                  '86': 0.14976638614599999, '87': 0.14942388535199999,
                                  '88': 0.14740916274999999, '89': 0.14821336952600001,
                                  '90': 0.14188941422699999, '91': 0.14039515298300001,
                                  '92': 0.14125100827199999, '93': 0.140135804694,
                                  '94': 0.13933483465099999, '95': 0.139679588617,
                                  '96': 0.13569859464199999, '97': 0.135394351192,
                                  '98': 0.13619473881800001, '99': 0.136671316751,
                                  '100': 0.135307208304}

                    self.similarity_threshold = thresholds[str(self.clustering_parameter)]
            elif self.current_similarity_measure == "custom":
                self.similarity_threshold = self.custom_threshold

        if not self.quiet:
            print "Similarity threshold:", self.similarity_threshold

        for index, unit in enumerate(self.parsed_response):
            next_word_index = index + 1
            collection = [unit] # begin current collection
            collection_index = [index] # begin current collection index list
            collection_terminus_found = False
            while not collection_terminus_found:
                if next_word_index < len(self.parsed_response):
                    # Check whether last word in attempt has been read
                    test = False
                    if self.current_collection_type == "cluster":
                        # Check whether next word is related to
                        # every other word in cluster
                        unit2 = self.parsed_response[next_word_index]
                        test = all([self.compute_similarity_score(unit2, other_unit) >= self.similarity_threshold \
                                for other_unit in collection])
                    elif self.current_collection_type == "chain":
                        #check whether the word is related to the one before it
                        #remember that we're testing words at the end of the chain, and creating new links
                        unit1 = self.parsed_response[next_word_index - 1]
                        unit2 = self.parsed_response[next_word_index]
                        test = self.compute_similarity_score(unit1,unit2) >= self.similarity_threshold
                    if test:
                        #add NEXT word
                        collection.append(self.parsed_response[next_word_index])
                        collection_index.append(next_word_index)
                        next_word_index += 1
                    else:

                        # Check whether cluster is subsequence of cluster
                        # already added to list
                        collection_index = ' '.join([str(w) for w in collection_index])
                        if collection_index not in str(self.collection_indices):
                            self.collection_indices.append(collection_index)
                            self.collection_sizes.append(len(collection))
                        collection_terminus_found = True
                else:
                    # Execute if word is last word in attempt
                    collection_index = ' '.join([str(w) for w in collection_index])
                    if collection_index not in str(self.collection_indices):
                        self.collection_indices.append(collection_index)
                        self.collection_sizes.append(len(collection))
                    collection_terminus_found = True

        # Get a list of collections and their positions in the response.
        for index in self.collection_indices:
            collection = []
            for i in index.split():
                collection.append(self.parsed_response[int(i)])
            self.collection_list.append(collection)