Parse the BLAST results produced above. Find primer pairs with full-length hits with mismatches equal or
        lesser than the cutoff value

def parseblast(self):
        """
        Parse the BLAST results produced above. Find primer pairs with full-length hits with mismatches equal or
        lesser than the cutoff value
        """
        for sample in self.metadata:
            if sample.general.bestassemblyfile != 'NA' and sample[self.analysistype].assemblyfile != 'NA':
                # Initialise variables
                sample[self.analysistype].blastresults = dict()
                sample[self.analysistype].contigs = dict()
                sample[self.analysistype].hits = dict()
                sample[self.analysistype].mismatches = dict()
                sample[self.analysistype].blastrecords = list()
                sample[self.analysistype].range = dict()
                sample[self.analysistype].genespresent = dict()
                # Open blast output csv file
                csvfile = open(sample[self.analysistype].report)
                # Skip header
                csvfile.readline()
                # Open the sequence profile file as a dictionary
                blastdict = DictReader(csvfile, fieldnames=self.fieldnames, dialect='excel-tab')

                # Go through each BLAST result
                for row in blastdict:
                    # Ensure that the hit is full-length, and that the number of mismatches is equal to or lesser
                    # than the supplied cutoff value
                    if int(row['alignment_length']) == self.faidict[row['subject_id']] and \
                                    int(row['mismatches']) <= self.mismatches:
                        # Add the current row to the list for future work
                        sample[self.analysistype].blastrecords.append(row)
                        # Populate the dictionaries with the contig name (e.g. CA_CFIA-515_NODE_1_length_1791),
                        # the gene name (e.g. vtx2a), and the primer name (e.g. vtx2a-R3_1) as required
                        # accounts for primer names with "-" in addition to the terminal "-F" or "-R"
                        try:
                            sample[self.analysistype].blastresults[row['query_id']].add(row['subject_id'])
                            sample[self.analysistype].contigs[row['query_id']].add('-'.join(row['subject_id']
                                                                                            .split('-')[:-1]))
                        except KeyError:
                            sample[self.analysistype].blastresults[row['query_id']] = set()
                            sample[self.analysistype].blastresults[row['query_id']].add(row['subject_id'])
                            sample[self.analysistype].contigs[row['query_id']] = set()
                            sample[self.analysistype].contigs[row['query_id']].add('-'.join(row['subject_id']
                                                                                            .split('-')[:-1]))
                # Check to see if both forward and reverse primers are present for a particular gene within a contig
                for contig, genes in sample[self.analysistype].contigs.items():
                    # Split off the primer details (e.g. vtx2a-R3_1 -> vtx2a-R) from the blast results dictionary in
                    # order to create a searchable list of primers
                    # accounts for primer names with "-" in addition to the terminal "-F" or "-R"
                    reformatted = {'-'.join(['-'.join(x.split('-')[:-1]), x.split('-')[-1][0]])
                                   for x in sample[self.analysistype].blastresults[contig]}
                    # Iterate through the list of genes to check if primers are present
                    for gene in genes:
                        # Add -F and -R to the gene, and ensure that both options are in the reformatted list of genes
                        # e.g. vtx2a-F and vtx2a-R in [vtx1a-R, vtx2c-F ,vtx2a-F, vtx2a-R]
                        if gene + '-F' in reformatted and gene + '-R' in reformatted:
                            # Extract the precise primers from the dictionary e.g. vtx2a use to
                            # find vtx2a-F2_4 (forward) and vtx2a-R3_1 (reverse)
                            forwardprimers = [primer for primer in sample[self.analysistype].blastresults[contig]
                                              if gene == primer.split('-F')[0]]
                            reverseprimers = [primer for primer in sample[self.analysistype].blastresults[contig]
                                              if gene == primer.split('-R')[0]]
                            # Concatenate the lists
                            primers = forwardprimers + reverseprimers
                            # Populate the dictionary with the primers
                            try:
                                sample[self.analysistype].hits[contig].append(primers)
                            except KeyError:
                                sample[self.analysistype].hits[contig] = list()
                                sample[self.analysistype].hits[contig].append(primers)

                            for record in sample[self.analysistype].blastrecords:
                                for primer in primers:
                                    if record['query_id'] == contig and record['subject_id'] == primer:
                                        # Populate the dictionary with the primers
                                        try:
                                            sample[self.analysistype].mismatches[contig][gene]\
                                                .update({primer: int(record['mismatches'])})
                                        except KeyError:
                                            try:
                                                sample[self.analysistype].mismatches[contig][gene] = dict()
                                                sample[self.analysistype].mismatches[contig][gene] = \
                                                    {primer: int(record['mismatches'])}
                                            except KeyError:
                                                sample[self.analysistype].mismatches[contig] = dict()
                                                sample[self.analysistype].mismatches[contig][gene] = dict()
                                                sample[self.analysistype].mismatches[contig][gene] = \
                                                    {primer: int(record['mismatches'])}
                # Use query the stored blast dictionary to find the location of the hits
                for row in sample[self.analysistype].blastrecords:
                    try:
                        # Extract the primers corresponding to the contig
                        for primers in sample[self.analysistype].hits[row['query_id']]:
                            # Extract the name of the contig
                            contig = row['query_id']
                            # Iterate through the forward and reverse primers
                            for primer in primers:
                                # If the primer is present in the current row, then this is the row of interest
                                if row['subject_id'] == primer:
                                    # Split off the primer direction and numbering
                                    # accounts for primer names with "-" in addition to the terminal "-F" or "-R"
                                    gene = '-'.join(primer.split('-')[:-1])
                                    # Populate a dictionary for storing the genes present - will be used in creating
                                    # the report
                                    try:
                                        sample[self.analysistype].genespresent[contig].add(gene)
                                    except KeyError:
                                        sample[self.analysistype].genespresent[contig] = set()
                                        sample[self.analysistype].genespresent[contig].add(gene)
                                    # Populate the range of the hit - the forward primer will have a -F an the name
                                    if '-F' in primer:
                                        # Determine if the sequence is the reverse complement - based on the fact that
                                        # this is the forward primer, if the contig is reversed, then the primer
                                        # (subject) will be reversed.
                                        if int(row['subject_start']) > int(row['subject_end']):
                                            # For reversed sequences, take the larger value of the start and stop
                                            data = max(int(row['query_start']), int(row['query_end']))
                                        else:
                                            # Otherwise take the smaller value
                                            data = min(int(row['query_start']), int(row['query_end']))
                                        # Add the appropriately calculated value to the range dictionary
                                        try:
                                            sample[self.analysistype].range[contig][gene].add(data)
                                        except KeyError:
                                            try:
                                                sample[self.analysistype].range[contig][gene] = set()
                                                sample[self.analysistype].range[contig][gene].add(data)
                                            except KeyError:
                                                sample[self.analysistype].range[contig] = dict()
                                                sample[self.analysistype].range[contig][gene] = set()
                                                sample[self.analysistype].range[contig][gene].add(data)

                                    # Similar to the forward primer, except reverse the min() and max()
                                    elif '-R' in primer:
                                        if int(row['subject_start']) < int(row['subject_end']):
                                            data = min(int(row['query_start']), int(row['query_end']))
                                        else:
                                            data = max(int(row['query_start']), int(row['query_end']))
                                        # Add the appropriately calculated value to the range dictionary
                                        try:
                                            sample[self.analysistype].range[contig][gene].add(data)
                                        except KeyError:
                                            try:
                                                sample[self.analysistype].range[contig][gene] = set()
                                                sample[self.analysistype].range[contig][gene].add(data)
                                            except KeyError:
                                                sample[self.analysistype].range[contig] = dict()
                                                sample[self.analysistype].range[contig][gene] = set()
                                                sample[self.analysistype].range[contig][gene].add(data)
                    except KeyError:
                        pass