<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def run_bwa(job, fastqs, sample_type, univ_options, bwa_options):
 """ This module aligns the SAMPLE_TYPE dna fastqs to the reference ARGUMENTS -- <ST> depicts the sample type. Substitute with 'tumor'/'normal' 1. fastqs: Dict of list of input WGS/WXS fastqs fastqs +- '<ST>_dna': [<JSid for 1.fastq> , <JSid for 2.fastq>] 2. sample_type: string of 'tumor_dna' or 'normal_dna' 3. univ_options: Dict of universal arguments used by almost all tools univ_options +- 'dockerhub': <dockerhub to use> 4. bwa_options: Dict of parameters specific to bwa bwa_options |- 'index_tar': <JSid for the bwa index tarball> +- 'n': <number of threads to allocate> RETURN VALUES 1. output_files: Dict of aligned bam + reference (nested return) output_files |- '<ST>_fix_pg_sorted.bam': <JSid> +- '<ST>_fix_pg_sorted.bam.bai': <JSid> This module corresponds to nodes 3 and 4 on the tree """

    job.fileStore.logToMaster('Running bwa on %s:%s' % (univ_options['patient'], sample_type))
    work_dir = job.fileStore.getLocalTempDir()
    fq_extn = '.gz' if fastqs['gzipped'] else ''
    input_files = {
        'dna_1.fastq' + fq_extn: fastqs[sample_type][0],
        'dna_2.fastq' + fq_extn: fastqs[sample_type][1],
        'bwa_index.tar.gz': bwa_options['index_tar']}
    input_files = get_files_from_filestore(job, input_files, work_dir, docker=True)
    parameters = ['mem',
                  '-t', str(bwa_options['n']),
                  '-v', '1',  # Don't print INFO messages to the stderr
                  '/'.join([input_files['bwa_index'], 'hg19.fa']),
                  input_files['dna_1.fastq'],
                  input_files['dna_2.fastq']]
    with open(''.join([work_dir, '/', sample_type, '_aligned.sam']), 'w') as samfile:
        docker_call(tool='bwa', tool_parameters=parameters, work_dir=work_dir,
                    dockerhub=univ_options['dockerhub'], outfile=samfile)
    # samfile.name retains the path info
    output_file = job.fileStore.writeGlobalFile(samfile.name)
    samfile_processing = job.wrapJobFn(bam_conversion, output_file, sample_type, univ_options,
                                       disk='60G')
    job.addChild(samfile_processing)
    # Return values get passed up the chain to here.  The return value will be a dict with
    # SAMPLE_TYPE_fix_pg_sorted.bam: jobStoreID
    # SAMPLE_TYPE_fix_pg_sorted.bam.bai: jobStoreID
    return samfile_processing.rv()