Find the best hit at a location, and discard any other matches
        :param report: Name of the blast output report being parsed
        :param sample: sample object

def uniqueblastparser(self, report, sample):
        """
        Find the best hit at a location, and discard any other matches
        :param report: Name of the blast output report being parsed
        :param sample: sample object
        """
        # Encountering the following error: # _csv.Error: field larger than field limit (131072)
        # According to https://stackoverflow.com/a/15063941, increasing the field limit should fix the issue
        csv.field_size_limit(sys.maxsize)
        # Open the sequence profile file as a dictionary
        blastdict = DictReader(open(report), fieldnames=self.fieldnames, dialect='excel-tab')
        # Initialise a dictionary to store all the target sequences
        sample[self.analysistype].targetsequence = dict()
        sample[self.analysistype].queryranges = dict()
        sample[self.analysistype].querypercent = dict()
        sample[self.analysistype].queryscore = dict()
        sample[self.analysistype].results = dict()
        # Go through each BLAST result
        for row in blastdict:
            print(row)
            # Calculate the percent identity and extract the bitscore from the row
            # Percent identity is the (length of the alignment - number of mismatches) / total subject length
            percentidentity = float('{:0.2f}'.format((float(row['positives'])) /
                                                     float(row['subject_length']) * 100))
            target = row['subject_id']
            contig = row['query_id']
            high = max([int(row['query_start']), int(row['query_end'])])
            low = min([int(row['query_start']), int(row['query_end'])])
            score = row['bit_score']
            # Create new entries in the blast results dictionaries with the calculated variables
            row['percentidentity'] = percentidentity
            row['low'] = low
            row['high'] = high
            row['alignment_fraction'] = float('{:0.2f}'.format(float(float(row['alignment_length']) /
                                                                     float(row['subject_length']) * 100)))
            # If the percent identity is greater than the cutoff
            if percentidentity >= self.cutoff:
                try:
                    sample[self.analysistype].results[contig].append(row)
                    # Boolean to store whether the list needs to be updated
                    append = True
                    # Iterate through all the ranges in the list - if the new range is different than any of the ranges
                    # seen before, append it. Otherwise, update the previous ranges with the new, longer range as
                    # necessary e.g. [2494, 3296] will be updated to [2493, 3296] with [2493, 3293], and
                    # [2494, 3296] will become [[2493, 3296], [3296, 4132]] with [3296, 4132]
                    for spot in sample[self.analysistype].queryranges[contig]:
                        # Update the low value if the new low value is slightly lower than before
                        if 1 <= (spot[0] - low) <= 100:
                            # Update the low value
                            spot[0] = low
                            # It is not necessary to append
                            append = False
                        # Update the previous high value if the new high value is slightly higher than before
                        elif 1 <= (high - spot[1]) <= 100:
                            # Update the high value in the list
                            spot[1] = high
                            # It is not necessary to append
                            append = False
                        # Do not append if the new low is slightly larger than before
                        elif 1 <= (low - spot[0]) <= 100:
                            append = False
                        # Do not append if the new high is slightly smaller than before
                        elif 1 <= (spot[1] - high) <= 100:
                            append = False
                        # Do not append if the high and low are the same as the previously recorded values
                        elif low == spot[0] and high == spot[1]:
                            append = False
                    # If the result appears to be in a new location, add the data to the object
                    if append:
                        sample[self.analysistype].queryranges[contig].append([low, high])
                        sample[self.analysistype].querypercent[contig] = percentidentity
                        sample[self.analysistype].queryscore[contig] = score
                # Initialise and populate the dictionary for each contig
                except KeyError:
                    sample[self.analysistype].queryranges[contig] = list()
                    sample[self.analysistype].queryranges[contig].append([low, high])
                    sample[self.analysistype].querypercent[contig] = percentidentity
                    sample[self.analysistype].queryscore[contig] = score
                    sample[self.analysistype].results[contig] = list()
                    sample[self.analysistype].results[contig].append(row)
                    sample[self.analysistype].targetsequence[target] = dict()
                # Determine if the query sequence is in a different frame than the subject, and correct
                # by setting the query sequence to be the reverse complement
                if int(row['subject_end']) < int(row['subject_start']):
                    # Create a sequence object using Biopython
                    seq = Seq(row['query_sequence'], IUPAC.unambiguous_dna)
                    # Calculate the reverse complement of the sequence
                    querysequence = str(seq.reverse_complement())
                # If the sequence is not reversed, use the sequence as it is in the output
                else:
                    querysequence = row['query_sequence']
                # Add the sequence in the correct orientation to the sample
                sample[self.analysistype].targetsequence[target] = querysequence