Run qualimap and parse the outputs
        :param sample: metadata object

def mapper(self, sample):
        """
        Run qualimap and parse the outputs
        :param sample: metadata object
        """
        if sample.general.bestassemblyfile != "NA":
            # Define the Qualimap log and report files
            reportfile = os.path.join(sample.general.QualimapResults, 'genome_results.txt')
            # Define the Qualimap call
            qualimapcall = 'qualimap bamqc -bam {} -outdir {}'.format(sample.general.sortedbam,
                                                                      sample.general.QualimapResults)
            sample.commands.qualimap = qualimapcall
            # Initialise a dictionary to hold the Qualimap results
            qdict = dict()
            # If the report file doesn't exist, run Qualimap, and print logs to the log file
            if not os.path.isfile(reportfile):
                tlock = threading.Lock()
                out, err = run_subprocess(sample.commands.qualimap)
                tlock.acquire()
                write_to_logfile(sample.commands.qualimap, sample.commands.qualimap, self.logfile,
                                 sample.general.logout, sample.general.logerr, None, None)
                write_to_logfile(out, err, self.logfile, sample.general.logout, sample.general.logerr, None, None)
                tlock.release()
            # Initialise a genobject to store the coverage dictionaries
            sample.depth = GenObject()
            sample.depth.length = dict()
            sample.depth.bases = dict()
            sample.depth.coverage = dict()
            sample.depth.stddev = dict()
            try:
                with open(reportfile) as report:
                    # Read the report
                    for line in report:
                        # Sanitise the keys and values using self.analyze
                        key, value = self.analyze(line)
                        # If the keys and values exist, enter them into the dictionary
                        if (key, value) != (None, None):
                            qdict[key] = value
                        if 'Coverage per contig' in line:
                            for contigline in report:
                                try:
                                    _, name, length, bases, coverage, stddev = contigline.rstrip().split('\t')
                                    sample.depth.length.update({name: length})
                                    sample.depth.bases.update({name: bases})
                                    sample.depth.coverage.update({name: coverage})
                                    sample.depth.stddev.update({name: stddev})
                                except ValueError:
                                    pass

            except (IOError, FileNotFoundError):
                pass
            # If there are values in the dictionary
            if qdict:
                # Make new category for Qualimap results and populate this category with the report data
                for attribute in qdict:
                    # Remove the 'X' from the depth values e.g. 40.238X
                    setattr(sample.mapping, attribute, qdict[attribute].rstrip('X'))