Create a report combining GeneSeekr and MOB Recon outputs

def geneseekrsummary(self):
        """
        Create a report combining GeneSeekr and MOB Recon outputs
        """
        logging.info('Creating predicted plasmid-borne gene summary table')
        with open(os.path.join(self.reportpath, 'plasmid_borne_summary.csv'), 'w') as pbs:
            data = 'Strain,Gene,PercentIdentity,Contig,Location,PlasmidIncompatibilitySets\n'
            for sample in self.metadata:
                # Create a flag to determine whether the strain name needs to be added to the data string if there
                # were no results
                result_bool = False
                # Initialise a dictionary to store a set of all the incompatibility types listed for a contig.
                # As the inc type will only be located on one of possibly several contigs associated with a predicted
                # plasmid, it is nice to know details about the plasmid
                inc_dict = dict()
                # Iterate through all the MOB recon outputs to populate the incompatibility set
                for primarykey, results in sample[self.analysistype].report_dict.items():
                    try:
                        inc = results['cluster_id']
                        # Convert the rep_type field (predicted incompatibilities) into a more a consistent
                        # format - pandas will call empty fields 'nan', which is a float
                        rep = str(results['rep_type']).replace(',', ';') if str(results['rep_type']) != 'nan' else 'ND'
                        # Add the incompatibility to the set
                        try:
                            inc_dict[inc].add(rep)
                        except KeyError:
                            inc_dict[inc] = set()
                            inc_dict[inc].add(rep)
                    except KeyError:
                        pass
                for primarykey, results in sample[self.analysistype].report_dict.items():
                    try:
                        contig = results['contig_id'].split('|')[1]
                        # Unicycler gives contigs names such as: 3_length=187116_depth=1.60x_circular=true - test
                        # to see if the contig name looks unicycler-like, and set the name appropriately (in this
                        # case, it would be 3)
                        if contig.split('_')[1].startswith('length'):
                            contig = contig.split('_')[0]
                        for gene, result_dict in sample.geneseekr_results.sampledata.items():
                            if contig == result_dict['query_id']:
                                percent_identity = result_dict['PercentIdentity']
                                # Set up the output string if the percent identity of the match is greater than the
                                # cutoff
                                if float(result_dict['PercentIdentity']) >= self.cutoff:
                                    # As there was at least a single gene passing the threshold, set the boolean to True
                                    result_bool = True
                                    data += '{sn},'.format(sn=sample.name)
                                    data += '{gene},{pi},{contig},{cid},{inc}\n'\
                                        .format(gene=gene,
                                                pi=percent_identity,
                                                contig=contig,
                                                cid=results['cluster_id'],
                                                inc=';'.join(sorted(inc_dict[str(results['cluster_id'])])))
                    except KeyError:
                        pass
                # If there were no results associated with the strain, make the row the strain name only
                if not result_bool:
                    data += '{sn}\n'.format(sn=sample.name)
            # Write the string to the report
            pbs.write(data)