Spawn a job to predict MHCI:peptide and MHCII:peptide binding on the input peptide file for each
    allele in in the input haplotype (phlat) files.

    :param dict transgened_files: Dict of tumor and normal peptide fsIDs and the tumor .map fsIDs
    :param dict phlat_files: Dict of MHCI and MHCII haplotypes
    :param dict univ_options: Dict of universal options used by almost all tools
    :param tuple mhc_options: Options specific to mhci and mhcii binding predictions
    :return: Tuple of dicts of mhci and mhcii predictions
                (mhci_preds, mhcii_preds)
                      |          |- <allele>:
                      |          |     |- 'tumor': fsID
                      |          |     +- 'normal': (fsID, str)
                      |          |
                      |          |- ...
                      |          |
                      |          +- <allele>:
                      |                |- 'tumor': fsID
                      |                +- 'normal': (fsID, str)
                      |
                      |- <allele>:
                      |     |- 'tumor': fsID
                      |     +- 'normal': fsID
                      |
                      |- ...
                      |
                      +- <allele>:
                            |- 'tumor': fsID
                            +- 'normal': fsID
    :rtype: tuple(dict, dict)

def spawn_antigen_predictors(job, transgened_files, phlat_files, univ_options, mhc_options):
    """
    Spawn a job to predict MHCI:peptide and MHCII:peptide binding on the input peptide file for each
    allele in in the input haplotype (phlat) files.

    :param dict transgened_files: Dict of tumor and normal peptide fsIDs and the tumor .map fsIDs
    :param dict phlat_files: Dict of MHCI and MHCII haplotypes
    :param dict univ_options: Dict of universal options used by almost all tools
    :param tuple mhc_options: Options specific to mhci and mhcii binding predictions
    :return: Tuple of dicts of mhci and mhcii predictions
                (mhci_preds, mhcii_preds)
                      |          |- <allele>:
                      |          |     |- 'tumor': fsID
                      |          |     +- 'normal': (fsID, str)
                      |          |
                      |          |- ...
                      |          |
                      |          +- <allele>:
                      |                |- 'tumor': fsID
                      |                +- 'normal': (fsID, str)
                      |
                      |- <allele>:
                      |     |- 'tumor': fsID
                      |     +- 'normal': fsID
                      |
                      |- ...
                      |
                      +- <allele>:
                            |- 'tumor': fsID
                            +- 'normal': fsID
    :rtype: tuple(dict, dict)
    """
    work_dir = os.getcwd()
    mhci_options, mhcii_options = mhc_options
    pept_files = {
        'T_9_mer.faa': transgened_files['transgened_tumor_9_mer_peptides.faa'],
        'N_9_mer.faa': transgened_files['transgened_normal_9_mer_peptides.faa'],
        'T_10_mer.faa': transgened_files['transgened_tumor_10_mer_peptides.faa'],
        'N_10_mer.faa': transgened_files['transgened_normal_10_mer_peptides.faa'],
        'T_15_mer.faa': transgened_files['transgened_tumor_15_mer_peptides.faa'],
        'N_15_mer.faa': transgened_files['transgened_normal_15_mer_peptides.faa']
    }
    input_files = {
        'mhci_alleles.list': phlat_files['mhci_alleles.list'],
        'mhcii_alleles.list': phlat_files['mhcii_alleles.list'],
        'mhci_restrictions.json.tar.gz': mhci_options['method_file'],
        'mhcii_restrictions.json.tar.gz': mhcii_options['method_file']}
    input_files = get_files_from_filestore(job, input_files, work_dir)
    for key in ('mhci_restrictions.json', 'mhcii_restrictions.json'):
        input_files[key] = untargz(input_files[key + '.tar.gz'], work_dir)

    mhci_alleles, mhcii_alleles = [], []
    with open(input_files['mhci_alleles.list'], 'r') as mhci_file:
        for line in mhci_file:
            mhci_alleles.append(line.strip())
    with open(input_files['mhcii_alleles.list'], 'r') as mhcii_file:
        for line in mhcii_file:
            mhcii_alleles.append(line.strip())
    # This file contains the list of allele:pept length combinations supported
    # by each prediction type.
    with open(input_files['mhci_restrictions.json'], 'r') as restfile:
        mhci_restrictions = json.load(restfile)
    with open(input_files['mhcii_restrictions.json'], 'r') as restfile:
        mhcii_restrictions = json.load(restfile)
    # For each mhci allele:peptfile combination, spawn a job and store the job handle in the dict.
    # Then do the same for mhcii
    mhci_preds, mhcii_preds = {}, {}
    for allele in mhci_alleles:
        for peplen in ['9', '10']:
            peptfile = peplen + '_mer.faa'
            # Ensure that the allele is among the list of accepted alleles
            try:
                if not mhci_restrictions[allele][peplen]:
                    continue
            except KeyError:
                continue
            mhci_job = job.addChildJobFn(predict_mhci_binding, pept_files['T_' + peptfile], allele,
                                         peplen, univ_options, mhci_options, disk='100M',
                                         memory='100M', cores=1)
            mhci_preds[(allele, peplen)] = mhci_job.addChildJobFn(
                predict_normal_binding,
                mhci_job.rv(),
                {x: y for x, y in pept_files.items() if peplen in x},
                allele,
                peplen,
                univ_options,
                mhci_options,
                disk='100M',
                memory='100M',
                cores=1).rv()
    for allele in mhcii_alleles:
        if allele not in mhcii_restrictions[mhcii_options['pred']]:
            continue
        mhcii_job = job.addChildJobFn(predict_mhcii_binding, pept_files['T_15_mer.faa'],  allele,
                                      univ_options, mhcii_options, disk='100M', memory='100M',
                                      cores=1)
        mhcii_preds[(allele, 15)] = mhcii_job.addFollowOnJobFn(
            predict_normal_binding,
            mhcii_job.rv(),
            {x: y for x, y in pept_files.items() if '15' in x},
            allele,
            '15',
            univ_options,
            mhcii_options,
            disk='100M',
            memory='100M',
            cores=1).rv()
    job.fileStore.logToMaster('Ran spawn_anti on %s successfully' % univ_options['patient'])
    return mhci_preds, mhcii_preds