def saveCompareHTML(outputDir,
                    chemkinPath1,
                    speciesDictPath1,
                    chemkinPath2,
                    speciesDictPath2,
                    readComments1=True,
                    readComments2=True):
    """
    Saves a model comparison HTML file based on two sets of chemkin and species dictionary
    files.
    """
    model1 = ReactionModel()
    model1.species, model1.reactions = loadChemkinFile(
        chemkinPath1, speciesDictPath1, readComments=readComments1)
    model2 = ReactionModel()
    model2.species, model2.reactions = loadChemkinFile(
        chemkinPath2, speciesDictPath2, readComments=readComments2)
    commonReactions, uniqueReactions1, uniqueReactions2 = compareModelReactions(
        model1, model2)
    commonSpecies, uniqueSpecies1, uniqueSpecies2 = compareModelSpecies(
        model1, model2)

    outputPath = outputDir + 'diff.html'
    saveDiffHTML(outputPath, commonSpecies, uniqueSpecies1, uniqueSpecies2,
                 commonReactions, uniqueReactions1, uniqueReactions2)
Ejemplo n.º 2
0
def save_compare_html(outputDir,
                      chemkin_path1,
                      species_dict_path1,
                      chemkin_path2,
                      species_dict_path2,
                      read_comments1=True,
                      read_comments2=True):
    """
    Saves a model comparison HTML file based on two sets of chemkin and species dictionary
    files.
    """
    model1 = ReactionModel()
    model1.species, model1.reactions = load_chemkin_file(
        chemkin_path1, species_dict_path1, read_comments=read_comments1)
    model2 = ReactionModel()
    model2.species, model2.reactions = load_chemkin_file(
        chemkin_path2, species_dict_path2, read_comments=read_comments2)
    common_reactions, unique_reactions1, unique_reactions2 = compare_model_reactions(
        model1, model2)
    common_species, unique_species1, unique_species2 = compare_model_species(
        model1, model2)

    output_path = outputDir + 'diff.html'
    save_diff_html(output_path, common_species, unique_species1,
                   unique_species2, common_reactions, unique_reactions1,
                   unique_reactions2)
Ejemplo n.º 3
0
def execute(inputModelFiles, **kwargs):

    try:
        wd = kwargs['wd']
    except KeyError:
        wd = os.getcwd()

    transport = kwargs['transport']

    outputChemkinFile = os.path.join(wd, 'chem.inp')
    outputSpeciesDictionary = os.path.join(wd, 'species_dictionary.txt')
    outputTransportFile = os.path.join(wd, 'tran.dat') if transport else None

    # Load the models to merge
    models = []
    for chemkin, speciesPath, transportPath in inputModelFiles:
        print 'Loading model #{0:d}...'.format(len(models) + 1)
        model = ReactionModel()
        model.species, model.reactions = loadChemkinFile(
            chemkin, speciesPath, transportPath=transportPath)
        models.append(model)

    finalModel = ReactionModel()
    for i, model in enumerate(models):
        print 'Ignoring common species and reactions from model #{0:d}...'.format(
            i + 1)
        Nspec0 = len(finalModel.species)
        Nrxn0 = len(finalModel.reactions)
        finalModel = finalModel.merge(model)
        Nspec = len(finalModel.species)
        Nrxn = len(finalModel.reactions)
        print 'Added {1:d} out of {2:d} ({3:.1f}%) unique species from model #{0:d}.'.format(
            i + 1, Nspec - Nspec0, len(model.species),
            (Nspec - Nspec0) * 100. / len(model.species))
        print 'Added {1:d} out of {2:d} ({3:.1f}%) unique reactions from model #{0:d}.'.format(
            i + 1, Nrxn - Nrxn0, len(model.reactions),
            (Nrxn - Nrxn0) * 100. / len(model.reactions))

    print 'The merged model has {0:d} species and {1:d} reactions'.format(
        len(finalModel.species), len(finalModel.reactions))

    # Save the merged model to disk
    saveChemkinFile(outputChemkinFile, finalModel.species,
                    finalModel.reactions)
    saveSpeciesDictionary(outputSpeciesDictionary, finalModel.species)
    if transport:
        saveTransportFile(outputTransportFile, finalModel.species)

    print 'Merged Chemkin file saved to {0}'.format(outputChemkinFile)
    print 'Merged species dictionary saved to {0}'.format(
        outputSpeciesDictionary)
    if transport:
        print 'Merged transport file saved to {0}'.format(outputTransportFile)
Ejemplo n.º 4
0
def get_models_to_merge(input_model_files):
    """
    Reads input file paths and creates a list of ReactionModel
    """
    models = []
    for chemkin, species_path, transport_path in input_model_files:
        print('Loading model #{0:d}...'.format(len(models) + 1))
        model = ReactionModel()
        model.species, model.reactions = load_chemkin_file(chemkin, species_path, transport_path=transport_path)
        models.append(model)
    return models
Ejemplo n.º 5
0
def combine_models(models):
    """
    Takes in a list of ReactionModels and and merges them into a single ReactionModel
    Reindexes species with the same label and index
    """
    final_model = ReactionModel()
    for i, model in enumerate(models):
        print('Ignoring common species and reactions from model #{0:d}...'.
              format(i + 1))
        nspec0 = len(final_model.species)
        nrxn0 = len(final_model.reactions)
        final_model = final_model.merge(model)
        nspec = len(final_model.species)
        nrxn = len(final_model.reactions)
        if len(model.species) > 0:
            print(
                'Added {1:d} out of {2:d} ({3:.1f}%) unique species from model '
                '#{0:d}.'.format(i + 1, nspec - nspec0, len(model.species),
                                 (nspec - nspec0) * 100. / len(model.species)))
        else:
            print('Added {1:d} out of {2:d} unique species from model '
                  '#{0:d}.'.format(i + 1, nspec - nspec0, len(model.species)))

        if len(model.reactions) > 0:
            print(
                'Added {1:d} out of {2:d} ({3:.1f}%) unique reactions from model '
                '#{0:d}.'.format(i + 1, nrxn - nrxn0, len(model.reactions),
                                 (nrxn - nrxn0) * 100. / len(model.reactions)))
        else:
            print('Added {1:d} out of {2:d} unique reactions from model '
                  '#{0:d}.'.format(i + 1, nrxn - nrxn0, len(model.reactions)))
    print('The merged model has {0:d} species and {1:d} reactions'
          ''.format(len(final_model.species), len(final_model.reactions)))

    # ensure no species with same name and index
    label_index_dict = {}
    for s in final_model.species:
        if s.label not in label_index_dict:
            label_index_dict[s.label] = [s.index]
        else:
            if s.index in label_index_dict[s.label]:
                # obtained a duplicate
                s.index = max(label_index_dict[s.label]) + 1
                print("Reindexed {0} due to dublicate labels and index".format(
                    s.label))
            label_index_dict[s.label].append(s.index)

    return final_model
Ejemplo n.º 6
0
    def test_1(self):
        """
        Test basic functionality of /tools/populate_reactions/
        """

        from rmgpy.chemkin import loadChemkinFile
        from rmgpy.rmg.model import ReactionModel

        inputFile = os.path.join(rmgpy.getPath(), 'tools', 'data', 'generate',
                                 'input.py')

        with open(inputFile) as fp:
            response = self.client.post('/tools/populate_reactions/',
                                        {'InputFile': fp})

        self.assertEqual(response.status_code, 200)

        folder = os.path.join(settings.MEDIA_ROOT, 'rmg', 'tools',
                              'populateReactions')

        # Check if inputs were correctly uploaded
        pyInput = os.path.join(folder, 'input.txt')

        self.assertTrue(os.path.isfile(pyInput),
                        'RMG input file was not uploaded')

        # Check if outputs were correctly generated
        htmlOutput = os.path.join(folder, 'output.html')
        chemOutput = os.path.join(folder, 'chemkin', 'chem.inp')
        dictOutput = os.path.join(folder, 'chemkin', 'species_dictionary.txt')

        self.assertTrue(os.path.isfile(htmlOutput),
                        'HTML Output was not generated')
        self.assertTrue(os.path.isfile(chemOutput),
                        'CHEMKIN file was not generated')
        self.assertTrue(os.path.isfile(dictOutput),
                        'Species dictionary was not generated')

        # Check that the output is not empty
        model = ReactionModel()
        model.species, model.reactions = loadChemkinFile(
            chemOutput, dictOutput)

        self.assertTrue(model.species, 'No species were generated')
        self.assertTrue(model.reactions, 'No reactions were generated')

        shutil.rmtree(folder)
Ejemplo n.º 7
0
def combine_models(models):
    """
    Takes in a list of ReactionModels and and merges them into a single ReactionModel
    Reindexes species with the same label and index
    """
    final_model = ReactionModel()
    for i, model in enumerate(models):
        print('Ignoring common species and reactions from model #{0:d}...'.
              format(i + 1))
        nspec0 = len(final_model.species)
        nrxn0 = len(final_model.reactions)
        final_model = final_model.merge(model)
        nspec = len(final_model.species)
        nrxn = len(final_model.reactions)
        if len(model.species) > 0:
            print(
                'Added {1:d} out of {2:d} ({3:.1f}%) unique species from model '
                '#{0:d}.'.format(i + 1, nspec - nspec0, len(model.species),
                                 (nspec - nspec0) * 100. / len(model.species)))
        else:
            print('Added {1:d} out of {2:d} unique species from model '
                  '#{0:d}.'.format(i + 1, nspec - nspec0, len(model.species)))

        if len(model.reactions) > 0:
            print(
                'Added {1:d} out of {2:d} ({3:.1f}%) unique reactions from model '
                '#{0:d}.'.format(i + 1, nrxn - nrxn0, len(model.reactions),
                                 (nrxn - nrxn0) * 100. / len(model.reactions)))
        else:
            print('Added {1:d} out of {2:d} unique reactions from model '
                  '#{0:d}.'.format(i + 1, nrxn - nrxn0, len(model.reactions)))
    print('The merged model has {0:d} species and {1:d} reactions'
          ''.format(len(final_model.species), len(final_model.reactions)))

    # reindex the unique species (to avoid name conflicts on save)
    speciesIndex = 0
    for spec in final_model.species:
        if spec.label not in ['Ar', 'N2', 'Ne', 'He']:
            spec.index = speciesIndex + 1
            speciesIndex += 1

    return final_model
Ejemplo n.º 8
0
    def test_save_output_html(self):
        """
        This example is to test if an HTML file can be generated
        for the provided chemkin model.
        """
        folder = os.path.join(os.path.dirname(__file__), 'test_data/saveOutputHTML/')

        chemkin_path = os.path.join(folder, 'eg6', 'chem_annotated.inp')
        dictionary_path = os.path.join(folder, 'eg6', 'species_dictionary.txt')

        # load_chemkin_file
        species, reactions = load_chemkin_file(chemkin_path, dictionary_path)

        # convert it into a reaction model:
        core = ReactionModel(species, reactions)
        cerm = CoreEdgeReactionModel(core)

        out = os.path.join(folder, 'output.html')
        save_output_html(out, cerm)

        self.assertTrue(os.path.isfile(out))
        os.remove(out)
        shutil.rmtree(os.path.join(folder, 'species'))
Ejemplo n.º 9
0
            inputModelFiles.append((model[0], model[1], None))
        elif len(model) == 3:
            transport = True
            inputModelFiles.append((model[0], model[1], model[2]))
        else:
            raise Exception
    
    outputChemkinFile = 'chem.inp'
    outputSpeciesDictionary = 'species_dictionary.txt'
    outputTransportFile = 'tran.dat' if transport else None
    
    # Load the models to merge
    models = []
    for chemkin, speciesPath, transportPath in inputModelFiles:
        print 'Loading model #{0:d}...'.format(len(models)+1)
        model = ReactionModel()
        model.species, model.reactions = loadChemkinFile(chemkin, speciesPath, transportPath=transportPath)
        models.append(model)

    allSpecies = []
    speciesIndices = [[] for i in range(len(models))]
    for i, model in enumerate(models):       
        speciesIndices[i] = []
        for j, species in enumerate(model.species):
            for index, species0 in enumerate(allSpecies):
                if species0.isIsomorphic(species):
                    speciesIndices[i].append(index)
                    break; 
            else:
                allSpecies.append(species)
                speciesIndices[i].append(allSpecies.index(species))
def main():

    fuelName = 'test'

    chemFile = 'chem_' + fuelName
    spcFile = 'spc_' + fuelName + '.txt'
    outputChemkinFile = chemFile + '_delete_DupThirdBodyRXNs.inp'
    chemFile += '.inp'

    model = ReactionModel()
    model.species, model.reactions = loadChemkinFile(chemFile, spcFile)

    # Delete redundant third body reactions
    thirdBodyRXNs = []
    deleteRedundantThirdBodyRXNs = []
    duplicateEndoRXNs = []

    for rxn in model.reactions:
        if isinstance(rxn.kinetics, ThirdBody):
            thirdBodyRXNs.append(rxn)

    for rxnThirdBody in thirdBodyRXNs:
        for rxnTest in model.reactions:
            if rxnThirdBody.index != rxnTest.index:
                if checkSpecificFormThirdBodyRXN(rxnThirdBody, rxnTest):
                    deleteRedundantThirdBodyRXNs.append(rxnTest)

    # Delete duplicate reactions caused by Intra_R_Add_Endocyclic and Intra_R_Add_Exocyclic
    # Delete the endo one.
    for rxn1 in [
            rxn for rxn in model.reactions
            if rxn.duplicate == True and rxn.family == 'Intra_R_Add_Exocyclic'
    ]:
        for rxn2 in [
                rxn for rxn in model.reactions if rxn.duplicate == True
                and rxn.family == 'Intra_R_Add_Endocyclic'
        ]:
            if rxn1.index != rxn2.index and rxn1.isIsomorphic(
                    rxn2, eitherDirection=True):
                duplicateEndoRXNs.append(rxn2)
                rxn1.duplicate = False

    print '--------------------------------------------'
    print 'The following {0} redundant third body reactions will be removed from the original model:'.format(
        len(deleteRedundantThirdBodyRXNs))
    for rxn in deleteRedundantThirdBodyRXNs:
        print rxn

    print '--------------------------------------------'
    print 'The following {0} duplicated Intra_R_Add_Endocyclic reactions will be removed from the original model:'.format(
        len(duplicateEndoRXNs))
    for rxn in duplicateEndoRXNs:
        print rxn

    print '--------------------------------------------'
    print 'The original model has {0} rxns'.format(len(model.reactions))
    for rxn in deleteRedundantThirdBodyRXNs + duplicateEndoRXNs:
        model.reactions.remove(rxn)
    print 'The final model has {0} rxns'.format(len(model.reactions))

    print 'Save the final model into chemkin file...'
    saveChemkinFile(outputChemkinFile, model.species, model.reactions)
Ejemplo n.º 11
0
def execute(chemkin1, species_dict1, thermo1, chemkin2, species_dict2, thermo2,
            **kwargs):
    model1 = ReactionModel()
    model1.species, model1.reactions = load_chemkin_file(chemkin1,
                                                         species_dict1,
                                                         thermo_path=thermo1)
    model2 = ReactionModel()
    model2.species, model2.reactions = load_chemkin_file(chemkin2,
                                                         species_dict2,
                                                         thermo_path=thermo2)

    common_species, unique_species1, unique_species2 = compare_model_species(
        model1, model2)
    common_reactions, unique_reactions1, unique_reactions2 = compare_model_reactions(
        model1, model2)

    try:
        diff_only = kwargs['diffOnly']
    except KeyError:
        diff_only = False

    try:
        common_diff_only = kwargs['commonDiffOnly']
    except KeyError:
        common_diff_only = False

    if diff_only or common_diff_only:
        common_species = [x for x in common_species if not identical_thermo(x)]
        common_reactions = [
            x for x in common_reactions if not identical_kinetics(x)
        ]

    if common_diff_only:
        unique_species1 = []
        unique_species2 = []
        unique_reactions1 = []
        unique_reactions2 = []

    try:
        web = kwargs['web']
    except KeyError:
        web = False

    if not web:
        logging.info('{0:d} species were found in both models:'.format(
            len(common_species)))
        for spec1, spec2 in common_species:
            logging.info('    {0!s}'.format(spec1))
            if spec1.thermo and spec2.thermo:
                spec1.molecule[0].get_symmetry_number()
                logging.info(
                    '        {0:7.2f} {1:7.2f} {2:7.2f} {3:7.2f} {4:7.2f} {5:7.2f} {6:7.2f} {7:7.2f} {8:7.2f}'
                    .format(
                        spec1.thermo.get_enthalpy(300) / 4184.,
                        spec1.thermo.get_entropy(300) / 4.184,
                        spec1.thermo.get_heat_capacity(300) / 4.184,
                        spec1.thermo.get_heat_capacity(400) / 4.184,
                        spec1.thermo.get_heat_capacity(500) / 4.184,
                        spec1.thermo.get_heat_capacity(600) / 4.184,
                        spec1.thermo.get_heat_capacity(800) / 4.184,
                        spec1.thermo.get_heat_capacity(1000) / 4.184,
                        spec1.thermo.get_heat_capacity(1500) / 4.184,
                    ))
                logging.info(
                    '        {0:7.2f} {1:7.2f} {2:7.2f} {3:7.2f} {4:7.2f} {5:7.2f} {6:7.2f} {7:7.2f} {8:7.2f}'
                    .format(
                        spec2.thermo.get_enthalpy(300) / 4184.,
                        spec2.thermo.get_entropy(300) / 4.184,
                        spec2.thermo.get_heat_capacity(300) / 4.184,
                        spec2.thermo.get_heat_capacity(400) / 4.184,
                        spec2.thermo.get_heat_capacity(500) / 4.184,
                        spec2.thermo.get_heat_capacity(600) / 4.184,
                        spec2.thermo.get_heat_capacity(800) / 4.184,
                        spec2.thermo.get_heat_capacity(1000) / 4.184,
                        spec2.thermo.get_heat_capacity(1500) / 4.184,
                    ))
        logging.info(
            '{0:d} species were only found in the first model:'.format(
                len(unique_species1)))
        for spec in unique_species1:
            logging.info('    {0!s}'.format(spec))
        logging.info(
            '{0:d} species were only found in the second model:'.format(
                len(unique_species2)))
        for spec in unique_species2:
            logging.info('    {0!s}'.format(spec))

        logging.info('{0:d} reactions were found in both models:'.format(
            len(common_reactions)))
        for rxn1, rxn2 in common_reactions:
            logging.info('    {0!s}'.format(rxn1))
            if rxn1.kinetics and rxn2.kinetics:
                logging.info(
                    '        {0:7.2f} {1:7.2f} {2:7.2f} {3:7.2f} {4:7.2f} {5:7.2f} {6:7.2f} {7:7.2f}'
                    .format(
                        math.log10(rxn1.kinetics.get_rate_coefficient(
                            300, 1e5)),
                        math.log10(rxn1.kinetics.get_rate_coefficient(
                            400, 1e5)),
                        math.log10(rxn1.kinetics.get_rate_coefficient(
                            500, 1e5)),
                        math.log10(rxn1.kinetics.get_rate_coefficient(
                            600, 1e5)),
                        math.log10(rxn1.kinetics.get_rate_coefficient(
                            800, 1e5)),
                        math.log10(
                            rxn1.kinetics.get_rate_coefficient(1000, 1e5)),
                        math.log10(
                            rxn1.kinetics.get_rate_coefficient(1500, 1e5)),
                        math.log10(
                            rxn1.kinetics.get_rate_coefficient(2000, 1e5)),
                    ))
                logging.info(
                    '        {0:7.2f} {1:7.2f} {2:7.2f} {3:7.2f} {4:7.2f} {5:7.2f} {6:7.2f} {7:7.2f}'
                    .format(
                        math.log10(rxn2.kinetics.get_rate_coefficient(
                            300, 1e5)),
                        math.log10(rxn2.kinetics.get_rate_coefficient(
                            400, 1e5)),
                        math.log10(rxn2.kinetics.get_rate_coefficient(
                            500, 1e5)),
                        math.log10(rxn2.kinetics.get_rate_coefficient(
                            600, 1e5)),
                        math.log10(rxn2.kinetics.get_rate_coefficient(
                            800, 1e5)),
                        math.log10(
                            rxn2.kinetics.get_rate_coefficient(1000, 1e5)),
                        math.log10(
                            rxn2.kinetics.get_rate_coefficient(1500, 1e5)),
                        math.log10(
                            rxn2.kinetics.get_rate_coefficient(2000, 1e5)),
                    ))
        logging.info(
            '{0:d} reactions were only found in the first model:'.format(
                len(unique_reactions1)))
        for rxn in unique_reactions1:
            logging.info('    {0!s}'.format(rxn))
        logging.info(
            '{0:d} reactions were only found in the second model:'.format(
                len(unique_reactions2)))
        for rxn in unique_reactions2:
            logging.info('    {0!s}'.format(rxn))

    logging.info("Saving output in diff.html")

    try:
        wd = kwargs['wd']
    except KeyError:
        wd = os.getcwd()

    output_path = os.path.join(wd, 'diff.html')
    save_diff_html(output_path, common_species, unique_species1,
                   unique_species2, common_reactions, unique_reactions1,
                   unique_reactions2)
    logging.info("Finished!")

    return common_species, unique_species1, unique_species2, common_reactions, unique_reactions1, unique_reactions2
def execute(chemkin1, speciesDict1, thermo1, chemkin2, speciesDict2, thermo2,
            **kwargs):

    model1 = ReactionModel()
    model1.species, model1.reactions = loadChemkinFile(chemkin1,
                                                       speciesDict1,
                                                       thermoPath=thermo1)
    model2 = ReactionModel()
    model2.species, model2.reactions = loadChemkinFile(chemkin2,
                                                       speciesDict2,
                                                       thermoPath=thermo2)

    commonSpecies, uniqueSpecies1, uniqueSpecies2 = compareModelSpecies(
        model1, model2)
    commonReactions, uniqueReactions1, uniqueReactions2 = compareModelReactions(
        model1, model2)

    try:
        diffOnly = kwargs['diffOnly']
    except KeyError:
        diffOnly = False

    try:
        commonDiffOnly = kwargs['commonDiffOnly']
    except KeyError:
        commonDiffOnly = False

    if diffOnly or commonDiffOnly:
        commonSpecies = filter(lambda x: not identicalThermo(x), commonSpecies)
        commonReactions = filter(lambda x: not identicalKinetics(x),
                                 commonReactions)

    if commonDiffOnly:
        uniqueSpecies1 = []
        uniqueSpecies2 = []
        uniqueReactions1 = []
        uniqueReactions2 = []

    try:
        web = kwargs['web']
    except KeyError:
        web = False

    if not web:
        logging.info('{0:d} species were found in both models:'.format(
            len(commonSpecies)))
        for spec1, spec2 in commonSpecies:
            logging.info('    {0!s}'.format(spec1))
            if spec1.thermo and spec2.thermo:
                spec1.molecule[0].getSymmetryNumber()
                logging.info(
                    '        {0:7.2f} {1:7.2f} {2:7.2f} {3:7.2f} {4:7.2f} {5:7.2f} {6:7.2f} {7:7.2f} {8:7.2f}'
                    .format(
                        spec1.thermo.getEnthalpy(300) / 4184.,
                        spec1.thermo.getEntropy(300) / 4.184,
                        spec1.thermo.getHeatCapacity(300) / 4.184,
                        spec1.thermo.getHeatCapacity(400) / 4.184,
                        spec1.thermo.getHeatCapacity(500) / 4.184,
                        spec1.thermo.getHeatCapacity(600) / 4.184,
                        spec1.thermo.getHeatCapacity(800) / 4.184,
                        spec1.thermo.getHeatCapacity(1000) / 4.184,
                        spec1.thermo.getHeatCapacity(1500) / 4.184,
                    ))
                logging.info(
                    '        {0:7.2f} {1:7.2f} {2:7.2f} {3:7.2f} {4:7.2f} {5:7.2f} {6:7.2f} {7:7.2f} {8:7.2f}'
                    .format(
                        spec2.thermo.getEnthalpy(300) / 4184.,
                        spec2.thermo.getEntropy(300) / 4.184,
                        spec2.thermo.getHeatCapacity(300) / 4.184,
                        spec2.thermo.getHeatCapacity(400) / 4.184,
                        spec2.thermo.getHeatCapacity(500) / 4.184,
                        spec2.thermo.getHeatCapacity(600) / 4.184,
                        spec2.thermo.getHeatCapacity(800) / 4.184,
                        spec2.thermo.getHeatCapacity(1000) / 4.184,
                        spec2.thermo.getHeatCapacity(1500) / 4.184,
                    ))
        logging.info(
            '{0:d} species were only found in the first model:'.format(
                len(uniqueSpecies1)))
        for spec in uniqueSpecies1:
            logging.info('    {0!s}'.format(spec))
        logging.info(
            '{0:d} species were only found in the second model:'.format(
                len(uniqueSpecies2)))
        for spec in uniqueSpecies2:
            logging.info('    {0!s}'.format(spec))

        logging.info('{0:d} reactions were found in both models:'.format(
            len(commonReactions)))
        for rxn1, rxn2 in commonReactions:
            logging.info('    {0!s}'.format(rxn1))
            if rxn1.kinetics and rxn2.kinetics:
                logging.info(
                    '        {0:7.2f} {1:7.2f} {2:7.2f} {3:7.2f} {4:7.2f} {5:7.2f} {6:7.2f} {7:7.2f}'
                    .format(
                        math.log10(rxn1.kinetics.getRateCoefficient(300, 1e5)),
                        math.log10(rxn1.kinetics.getRateCoefficient(400, 1e5)),
                        math.log10(rxn1.kinetics.getRateCoefficient(500, 1e5)),
                        math.log10(rxn1.kinetics.getRateCoefficient(600, 1e5)),
                        math.log10(rxn1.kinetics.getRateCoefficient(800, 1e5)),
                        math.log10(rxn1.kinetics.getRateCoefficient(1000,
                                                                    1e5)),
                        math.log10(rxn1.kinetics.getRateCoefficient(1500,
                                                                    1e5)),
                        math.log10(rxn1.kinetics.getRateCoefficient(2000,
                                                                    1e5)),
                    ))
                logging.info(
                    '        {0:7.2f} {1:7.2f} {2:7.2f} {3:7.2f} {4:7.2f} {5:7.2f} {6:7.2f} {7:7.2f}'
                    .format(
                        math.log10(rxn2.kinetics.getRateCoefficient(300, 1e5)),
                        math.log10(rxn2.kinetics.getRateCoefficient(400, 1e5)),
                        math.log10(rxn2.kinetics.getRateCoefficient(500, 1e5)),
                        math.log10(rxn2.kinetics.getRateCoefficient(600, 1e5)),
                        math.log10(rxn2.kinetics.getRateCoefficient(800, 1e5)),
                        math.log10(rxn2.kinetics.getRateCoefficient(1000,
                                                                    1e5)),
                        math.log10(rxn2.kinetics.getRateCoefficient(1500,
                                                                    1e5)),
                        math.log10(rxn2.kinetics.getRateCoefficient(2000,
                                                                    1e5)),
                    ))
        logging.info(
            '{0:d} reactions were only found in the first model:'.format(
                len(uniqueReactions1)))
        for rxn in uniqueReactions1:
            logging.info('    {0!s}'.format(rxn))
        logging.info(
            '{0:d} reactions were only found in the second model:'.format(
                len(uniqueReactions2)))
        for rxn in uniqueReactions2:
            logging.info('    {0!s}'.format(rxn))

    logging.info("Saving output in diff.html")

    try:
        wd = kwargs['wd']
    except KeyError:
        wd = os.getcwd()

    outputPath = os.path.join(wd, 'diff.html')
    saveDiffHTML(outputPath, commonSpecies, uniqueSpecies1, uniqueSpecies2,
                 commonReactions, uniqueReactions1, uniqueReactions2)
    logging.info("Finished!")

    return commonSpecies, uniqueSpecies1, uniqueSpecies2, commonReactions, uniqueReactions1, uniqueReactions2