コード例 #1
0
def setUpModule():
    """A function that is run ONCE before all unit tests in this module."""
    global database
    database = RMGDatabase()
    database.load(
        path=os.path.join(settings['test_data.directory'], 'testing_database'),
        thermoLibraries=['primaryThermoLibrary'],
        reactionLibraries=['GRI-Mech3.0'],
        kineticsFamilies=[
            'R_Recombination',
            'Disproportionation',
            'R_Addition_MultipleBond',
            'H_Abstraction',
            'intra_H_migration',
        ],
        testing=True,
        depository=False,
        solvation=False,
    )
    #load empty forbidden structures to avoid any dependence on forbidden structures
    #for these tests
    for family in database.kinetics.families.values():
        family.forbidden = ForbiddenStructures()
    database.forbiddenStructures = ForbiddenStructures()

    # Prepare the database by loading training reactions and averaging the rate rules
    for family in database.kinetics.families.values():
        family.addKineticsRulesFromTrainingSet(thermoDatabase=database.thermo)
        family.fillKineticsRulesByAveragingUp(verbose=True)
コード例 #2
0
def export(input, output, database=None):

    print 'Loading the new RMG-Py database...'
    if not database:
        database = RMGDatabase()
    database.load(input)

    print 'Constructing additional rate rules from kinetics depository...'
    for family in database.kinetics.families.values():
        generateRules(family, database)

    print 'Saving old RMG-Java database...'
    database.saveOld(output)
コード例 #3
0
def export(input, output, database=None):

    print 'Loading the new RMG-Py database...'
    if not database:
        database = RMGDatabase()
    database.load(input)

    print 'Constructing additional rate rules from kinetics depository...'
    for family in database.kinetics.families.values():
        generateRules(family, database)

    print 'Saving old RMG-Java database...'
    database.saveOld(output)
コード例 #4
0
def TS_Database_Update(families, path=None, auto_save=False):
    """
    Expects list of reaction families

    Loads RMG Databse,
    Creaes instance of TS_updater for each reaction family in families,

    Return dictionary of family:family's instance of the updater
    """

    assert isinstance(
        families, list), "Families must be a list. If singular family, still keep it in list"
    acceptable_families = os.listdir(os.path.join(
        os.path.expandvars("$AUTOTST"), "database"))
    for family in families:
        assert isinstance(
            family, str), "Family names must be provided as strings"
        if family.upper() not in (family.upper()
                                  for family in acceptable_families):
            logging.warning(
                '"{}" is not a known Kinetics Family'.format(family))
            families.remove(family)

    logging.info("Loading RMG Database...")
    rmg_database = RMGDatabase()
    database_path = os.path.join(os.path.expandvars(
        '$RMGpy'), "..", 'RMG-database', 'input')

    try:
        rmg_database.load(database_path,
                          # kineticsFamilies=['H_Abstraction'],
                          kineticsFamilies=families,
                          transportLibraries=[],
                          reactionLibraries=[],
                          seedMechanisms=[],
                          thermoLibraries=[
                              'primaryThermoLibrary', 'thermo_DFT_CCSDTF12_BAC', 'CBS_QB3_1dHR'],
                          solvation=False,
                          )
    except BaseException:
        logging.error(
            "Failed to Load RMG Database at {}".format(database_path))

    Databases = {family: DatabaseUpdater(
        family, rmg_database, path=path) for family in families}

    if auto_save:
        save_all_individual_databases(Databases)

    return Databases
コード例 #5
0
def database_setup():
    # load RMG database to create reactions
    database = RMGDatabase()

    database.load(
        path = settings['database.directory'], 
        thermoLibraries = ['primaryThermoLibrary'], # can add others if necessary
        kineticsFamilies = 'all', 
        reactionLibraries = [], 
        kineticsDepositories = ''
    )

    thermodb = database.thermo
    print thermodb.libraries.keys()
コード例 #6
0
def export(input, output, database=None):

    print 'Loading the new RMG-Py database...'
    if not database:
        database = RMGDatabase()
    database.load(input, kineticsFamilies='all', kineticsDepositories='all')

    print 'Constructing additional rate rules from kinetics depository...'
    for family in database.kinetics.families.values():
        family.addKineticsRulesFromTrainingSet(thermoDatabase=database.thermo)

    print "Deleting thermo library entries with atoms RMG-Java can't understand..."
    database.thermo.pruneHeteroatoms(allowed=['C', 'H', 'O', 'S'])
    print 'Saving old RMG-Java database...'
    database.saveOld(output)
    print "Done!"
コード例 #7
0
def export(input, output, database=None):

    print 'Loading the new RMG-Py database...'
    if not database:
        database = RMGDatabase()
    database.load(input, kineticsFamilies='all', kineticsDepositories='all')

    print 'Constructing additional rate rules from kinetics depository...'    
    for family in database.kinetics.families.values():
        family.addKineticsRulesFromTrainingSet(thermoDatabase=database.thermo)

    print "Deleting thermo library entries with atoms RMG-Java can't understand..."
    database.thermo.pruneHeteroatoms(allowed=['C','H','O','S'])
    print 'Saving old RMG-Java database...'
    database.saveOld(output)
    print "Done!"
コード例 #8
0
def setUpModule():
    """A function that is run ONCE before all unit tests in this module."""
    global database
    database = RMGDatabase()
    database.load(
        path=os.path.join(settings['test_data.directory'], 'testing_database'),
        kinetics_families=['H_Abstraction', 'intra_H_migration'],
        testing=True,
        depository=False,
        solvation=False,
    )
    database.load_forbidden_structures()

    # Prepare the database by loading training reactions and averaging the rate rules
    for family in database.kinetics.families.values():
        family.add_rules_from_training(thermo_database=database.thermo)
        family.fill_rules_by_averaging_up(verbose=True)
コード例 #9
0
def setUpModule():
    """A function that is run ONCE before all unit tests in this module."""
    global database
    database = RMGDatabase()
    database.load(
        path=os.path.join(settings['test_data.directory'], 'testing_database'),
        kineticsFamilies=[
            'H_Abstraction','intra_H_migration'
        ],
        testing=True,
        depository=False,
        solvation=False,
    )
    database.loadForbiddenStructures()

    # Prepare the database by loading training reactions and averaging the rate rules
    for family in database.kinetics.families.values():
        family.addKineticsRulesFromTrainingSet(thermoDatabase=database.thermo)
        family.fillKineticsRulesByAveragingUp(verbose=True)
コード例 #10
0
ファイル: generateTree.py プロジェクト: shihchengli/RMG-Py
def main():
    initialize_log(logging.INFO, 'treegen.log')
    dbdir = settings['database.directory']
    family_name = parse_arguments()
    database = RMGDatabase()
    database.load(
        path=dbdir,
        thermo_libraries=[
            'Klippenstein_Glarborg2016', 'BurkeH2O2',
            'thermo_DFT_CCSDTF12_BAC', 'DFT_QCI_thermo',
            'primaryThermoLibrary', 'primaryNS', 'NitrogenCurran', 'NOx2018',
            'FFCM1(-)', 'SulfurLibrary', 'SulfurGlarborgH2S', 'SABIC_aromatics'
        ],
        transport_libraries=[],
        reaction_libraries=[],
        seed_mechanisms=[],
        kinetics_families=[family_name],
        kinetics_depositories=['training'],
        # frequenciesLibraries = self.statmechLibraries,
        depository=
        False,  # Don't bother loading the depository information, as we don't use it
    )
    family = database.kinetics.families[family_name]
    num_training_rxns = len(family.get_training_depository().entries)
    max_batch_size = 800
    family.clean_tree()
    if (num_training_rxns / max_batch_size >
            1) and (num_training_rxns / max_batch_size <= 1.3):
        family.generate_tree(thermo_database=database.thermo,
                             nprocs=1,
                             max_batch_size=num_training_rxns)
    else:
        family.generate_tree(thermo_database=database.thermo, nprocs=1)
    family.check_tree()
    family.regularize()
    template_rxn_map = family.get_reaction_matches(
        thermo_database=database.thermo,
        remove_degeneracy=True,
        get_reverse=True,
        fix_labels=True)
    family.make_bm_rules_from_template_rxn_map(template_rxn_map, nprocs=1)
    family.check_tree()
    family.save(os.path.join(dbdir, 'kinetics', 'families', family_name))
コード例 #11
0
def simple_react():
    # load RMG database to create reactions
    database = RMGDatabase()

    database.load(
        path = settings['database.directory'], 
        thermoLibraries = ['primaryThermoLibrary'], # can add others if necessary
        kineticsFamilies = 'all', 
        reactionLibraries = [], 
        kineticsDepositories = ''
    )

    kinetics_db = database.kinetics
    mol = Molecule().fromSMILES('CC')

    reactants = [mol]
    return kinetics_db.react_molecules(reactants, 
                           only_families=['R_Recombination'],
                           prod_resonance=False)
コード例 #12
0
def setUpModule():
    """A function that is run ONCE before all unit tests in this module."""
    global database
    database = RMGDatabase()
    database.load(
        path=os.path.join(settings['test_data.directory'], 'testing_database'),
        thermoLibraries=['primaryThermoLibrary'],
        reactionLibraries=['GRI-Mech3.0'],
        kineticsFamilies=[
            'R_Recombination',
            'Disproportionation',
            'R_Addition_MultipleBond',
        ],
        testing=True,
        depository=False,
        solvation=False,
    )
    database.loadForbiddenStructures()

    # Prepare the database by loading training reactions and averaging the rate rules
    for family in database.kinetics.families.values():
        family.addKineticsRulesFromTrainingSet(thermoDatabase=database.thermo)
        family.fillKineticsRulesByAveragingUp(verbose=True)
コード例 #13
0
def load_mechanism(mech_file, dict_file):
    """
    Loads the RMG database and processes a chemical mechanism. 
    
    Returns loaded rmgpy.data.rmg.RMGDatabase(), list of 
    reactions and their families, and species dictionary
    """
    print 'Loading RMG Database ...'
    families = ['Silylene_Insertion', 'H_Abstraction']
    rmgDatabase = RMGDatabase()
    rmgDatabase.load(os.path.abspath(
        os.path.join(os.getenv('RMGpy'), '..', 'RMG-database', 'input')),
                     kineticsFamilies=families,
                     seedMechanisms=[],
                     solvation=False)
    print 'Finished loading RMG Database ...'

    loadSpecies = rmgDatabase.kinetics.families[
        families[0]]  # any family will do
    species_dict = loadSpecies.getSpecies(dict_file)

    file_object = open(mech_file, 'r')
    mechLines = file_object.readlines()

    rxnList = []
    gotit = []
    for k, line in enumerate(mechLines):
        if line.startswith('! Template reaction:'):
            for m in range(10):
                reaction = mechLines[k + m].split()[0]
                if not reaction.startswith('!'):
                    break
            if reaction not in gotit:
                gotit.append(reaction)
                rxnList.append((line.split(': ')[1], mechLines[k + m]))

    return rmgDatabase, rxnList, species_dict
コード例 #14
0
ファイル: kineticsGroups.py プロジェクト: KEHANG/RMG-database
def loadDatabase():
    print 'Loading RMG database...'
    from rmgpy.data.rmg import RMGDatabase
    database = RMGDatabase()
    database.load('input')
    return database
コード例 #15
0
"""

import math
import os.path
import sys
import time
import subprocess
import os

from rmgpy.kinetics import KineticsData
from rmgpy.data.kinetics import KineticsDatabase, KineticsGroups
from rmgpy.data.rmg import RMGDatabase

    
################################################################################

if __name__ == '__main__':

    # Set the import and export paths
    oldPath = 'input'
    newPath = 'input_new'
        
    print 'Loading old RMG-Py database...'
    database = RMGDatabase()
    database.load(oldPath, kineticsFamilies='all', kineticsDepositories='all')
    
      
    print 'Saving the new RMG-Py database...'
    database.save(newPath)
    print "Done!"
コード例 #16
0
                        nargs=1,
                        help='the family to use')
    parser.add_argument(
        'kinetics_depository',
        metavar='<kinetics_depository>',
        type=str,
        nargs='+',
        help='the kineticsDepository to use, e.g., training, NIST')

    args = parser.parse_args()

    print('Loading RMG database...')
    from rmgpy.data.rmg import RMGDatabase
    from rmgpy import settings
    database = RMGDatabase()
    database.load(settings['database.directory'],
                  kinetics_families=args.kinetics_family,
                  kinetics_depositories=args.kinetics_depository)

    family = database.kinetics.families.get(args.kinetics_family[0])

    print('Generating Evans-Polanyi data...')
    for depository in family.depositories:
        try:
            generate_evans_polanyi_plot(depository, database)
        except KeyError:
            print(e)
            print('The specified depository "{0}" was invalid.'.format(
                depository))
            quit()
コード例 #17
0
class Uncertainty:
    """
    This class contains functions associated with running uncertainty analyses
    for a single RMG-generated mechanism.
    """
    def __init__(self,
                 speciesList=None,
                 reactionList=None,
                 outputDirectory=''):
        """
        `speciesList`: list of RMG species objects
        `reactionList`: list of RMG reaction objects
        `outputDirectoy`: directory path for saving output files from the analyses
        """
        self.database = None
        self.speciesList = speciesList
        self.reactionList = reactionList
        self.speciesSourcesDict = None
        self.reactionSourcesDict = None
        self.allThermoSources = None
        self.allKineticSources = None
        self.thermoInputUncertainties = None
        self.kineticInputUncertainties = None
        self.outputDirectory = outputDirectory if outputDirectory else os.getcwd(
        )

        # Make output directory if it does not yet exist:
        if not os.path.exists(self.outputDirectory):
            try:
                os.makedirs(self.outputDirectory)
            except:
                raise Exception(
                    'Uncertainty output directory could not be created.')

    def loadDatabase(self,
                     kineticsFamilies='all',
                     kineticsDepositories=None,
                     thermoLibraries=None,
                     reactionLibraries=None):
        """
        This function loads a single copy of the RMGDatabase with full verbose averaging
        of the rate rule to trace kinetics sources.  
        
        By default, this function loads all the kinetics families, only the training kinetics depository,
        the primaryThermoLibrary, and no reaction libraries.  
        """
        from rmgpy.data.rmg import RMGDatabase
        from rmgpy import settings

        if not kineticsDepositories:
            kineticsDepositories = ['training']
        if not thermoLibraries:
            thermoLibraries = ['primaryThermoLibrary']
        if not reactionLibraries:
            reactionLibraries = []

        self.database = RMGDatabase()
        self.database.load(
            settings['database.directory'],
            kineticsFamilies=kineticsFamilies,
            kineticsDepositories=kineticsDepositories,
            thermoLibraries=thermoLibraries,
            reactionLibraries=reactionLibraries,
        )

        # Prepare the database by loading training reactions but not averaging the rate rules
        for familyLabel, family in self.database.kinetics.families.iteritems():
            family.addKineticsRulesFromTrainingSet(
                thermoDatabase=self.database.thermo)

            family.fillKineticsRulesByAveragingUp(verbose=True)

    def loadModel(self, chemkinPath, dictionaryPath, transportPath=None):
        """
        Load a RMG-generated model into the Uncertainty class
        `chemkinPath`: path to the chem_annotated.inp CHEMKIN mechanism 
        `dictionaryPath`: path to the species_dictionary.txt file 
        `transportPath`: path to the tran.dat file (optional)

        Then create dictionaries stored in self.thermoGroups and self.rateRules
        containing information about the source of the thermodynamic and kinetic
        parameters
        """
        from rmgpy.chemkin import loadChemkinFile

        self.speciesList, self.reactionList = loadChemkinFile(
            chemkinPath,
            dictionaryPath=dictionaryPath,
            transportPath=transportPath)

    def extractSourcesFromModel(self):
        """
        Extract the source data from the model using its comments.
        Must be done after loading model and database to work.
        """
        self.speciesSourcesDict = {}
        for species in self.speciesList:
            source = self.database.thermo.extractSourceFromComments(species)

            # Now prep the source data
            # Do not alter the GAV information, but reassign QM and Library sources to the species indices that they came from
            if len(source.keys()) == 1:
                # The thermo came from a single source, so we know it comes from a value describing the exact species
                if 'Library' in source:
                    source['Library'] = self.speciesList.index(
                        species
                    )  # Use just the species index in self.speciesList, for better shorter printouts when debugging
                if 'QM' in source:
                    source['QM'] = self.speciesList.index(species)

            elif len(source.keys()) == 2:
                # The thermo has two sources, which indicates it's an HBI correction on top of a library or QM value.  We must retrieve the original
                # saturated molecule's thermo instead of using the radical species as the source of thermo
                saturatedSpecies = retrieveSaturatedSpeciesFromList(
                    species, self.speciesList)
                if 'Library' in source:
                    source['Library'] = self.speciesList.index(
                        saturatedSpecies)
                if 'QM' in source:
                    source['QM'] = self.speciesList.index(saturatedSpecies)
            else:
                raise Exception(
                    'Source of thermo should not use more than two sources out of QM, Library, or GAV.'
                )

            self.speciesSourcesDict[species] = source

        self.reactionSourcesDict = {}
        for reaction in self.reactionList:
            source = self.database.kinetics.extractSourceFromComments(reaction)
            # Prep the source data
            # Consider any library or PDep reaction to be an independent parameter for now and assign the source to the index of the
            # reaction within self.reactionList
            if 'Library' in source:
                source['Library'] = self.reactionList.index(reaction)
            elif 'PDep' in source:
                source['PDep'] = self.reactionList.index(reaction)
            elif 'Training' in source:
                # Do nothing here because training source already saves the entry from the training reaction
                pass
            elif 'Rate Rules' in source:
                # Do nothing
                pass
            else:
                raise Exception(
                    'Source of kinetics must be either Library, PDep, Training, or Rate Rules'
                )
            self.reactionSourcesDict[reaction] = source

        # Account for all the thermo sources
        allThermoSources = {'GAV': {}, 'Library': set(), 'QM': set()}
        for source in self.speciesSourcesDict.values():
            if 'GAV' in source:
                for groupType in source['GAV'].keys():
                    groupEntries = [
                        groupTuple[0]
                        for groupTuple in source['GAV'][groupType]
                    ]
                    if not groupType in allThermoSources['GAV']:
                        allThermoSources['GAV'][groupType] = set(groupEntries)
                    else:
                        allThermoSources['GAV'][groupType].update(groupEntries)
            if 'Library' in source:
                allThermoSources['Library'].add(source['Library'])
            if 'QM' in source:
                allThermoSources['QM'].add(source['QM'])

        # Convert to lists
        self.allThermoSources = {}
        self.allThermoSources['Library'] = list(allThermoSources['Library'])
        self.allThermoSources['QM'] = list(allThermoSources['QM'])
        self.allThermoSources['GAV'] = {}
        for groupType in allThermoSources['GAV'].keys():
            self.allThermoSources['GAV'][groupType] = list(
                allThermoSources['GAV'][groupType])

        # Account for all the kinetics sources
        allKineticSources = {
            'Rate Rules': {},
            'Training': {},
            'Library': [],
            'PDep': []
        }
        for source in self.reactionSourcesDict.values():
            if 'Training' in source:
                familyLabel = source['Training'][0]
                trainingEntry = source['Training'][1]
                if not familyLabel in allKineticSources['Training']:
                    allKineticSources['Training'][familyLabel] = set(
                        [trainingEntry])
                else:
                    allKineticSources['Training'][familyLabel].add(
                        trainingEntry)
            elif 'Library' in source:
                allKineticSources['Library'].append(source['Library'])
            elif 'PDep' in source:
                allKineticSources['PDep'].append(source['PDep'])
            elif 'Rate Rules' in source:
                familyLabel = source['Rate Rules'][0]
                sourceDict = source['Rate Rules'][1]
                rules = sourceDict['rules']
                training = sourceDict['training']
                if rules:
                    ruleEntries = [ruleTuple[0] for ruleTuple in rules]
                    if not familyLabel in allKineticSources['Rate Rules']:
                        allKineticSources['Rate Rules'][familyLabel] = set(
                            ruleEntries)
                    else:
                        allKineticSources['Rate Rules'][familyLabel].update(
                            ruleEntries)
                if training:
                    # Even though they are from training reactions, we consider the rate rules derived from the training
                    # reactions to be noncorrelated, due to the fact that some may be reversed.
                    trainingRules = [
                        trainingTuple[0] for trainingTuple in training
                    ]  # Pick the rate rule entries
                    if not familyLabel in allKineticSources['Rate Rules']:
                        allKineticSources['Rate Rules'][familyLabel] = set(
                            trainingRules)
                    else:
                        allKineticSources['Rate Rules'][familyLabel].update(
                            trainingRules)

        self.allKineticSources = {}
        self.allKineticSources['Library'] = allKineticSources['Library']
        self.allKineticSources['PDep'] = allKineticSources['PDep']
        # Convert to lists
        self.allKineticSources['Rate Rules'] = {}
        for familyLabel in allKineticSources['Rate Rules'].keys():
            self.allKineticSources['Rate Rules'][familyLabel] = list(
                allKineticSources['Rate Rules'][familyLabel])

        self.allKineticSources['Training'] = {}
        for familyLabel in allKineticSources['Training'].keys():
            self.allKineticSources['Training'][familyLabel] = list(
                allKineticSources['Training'][familyLabel])

    def assignParameterUncertainties(
        self,
        gParamEngine=ThermoParameterUncertainty(),
        kParamEngine=KineticParameterUncertainty()):
        """
        Assign uncertainties based on the sources of the species thermo and reaction kinetics.
        """

        self.thermoInputUncertainties = []
        self.kineticInputUncertainties = []

        for species in self.speciesList:
            dG = gParamEngine.getUncertaintyValue(
                self.speciesSourcesDict[species])
            self.thermoInputUncertainties.append(dG)
        for reaction in self.reactionList:
            dlnk = kParamEngine.getUncertaintyValue(
                self.reactionSourcesDict[reaction])
            self.kineticInputUncertainties.append(dlnk)
コード例 #18
0
ファイル: evansPolanyi.py プロジェクト: yfyh2013/RMG-database
    parser = argparse.ArgumentParser()
    parser.add_argument('depository',
                        metavar='<depository>',
                        type=str,
                        nargs=1,
                        help='the depository to use')

    args = parser.parse_args()

    print 'Loading RMG database...'
    from rmgpy.data.rmg import RMGDatabase
    from rmgpy import settings
    database = RMGDatabase()
    database.load(settings['database.directory'],
                  kineticsFamilies='all',
                  kineticsDepositories='all')

    try:
        depositories = [
            database.kinetics.depository[label] for label in args.depository
        ]
    except KeyError:
        print e
        print 'The specified depository "{0}" was invalid.'.format(label)
        quit()

    print 'Generating Evans-Polanyi data...'
    for depository in depositories:
        generateEvansPolanyiPlot(depository, database)
コード例 #19
0
ファイル: reaction.py プロジェクト: C-Underkoffler/AutoTST
    def load_databases(cls, force_reload=False):
        """
        Load the RMG and AutoTST databases, if they have not already been loaded,
        into the class level variables where they are stored.

        :param force_reload: if set to True then forces a reload, even if already loaded.
        :return: None
        """
        if cls.rmg_database and cls.ts_databases and not force_reload:
            return

        rmg_database = RMGDatabase()
        database_path = rmgpy.settings['database.directory']

        logging.info("Loading RMG database from '{}'".format(database_path))

        try:
            rmg_database.load(
                database_path,
                kineticsFamilies=cls.possible_families,
                transportLibraries=[],
                reactionLibraries=[],
                seedMechanisms=[],
                thermoLibraries=[
                    'primaryThermoLibrary', 'thermo_DFT_CCSDTF12_BAC',
                    'CBS_QB3_1dHR'
                ],
                solvation=False,
            )
        except IOError:
            logging.info(
                "RMG database not found at '{}'. This can occur if a git repository of the database is being"
                "used rather than the binary version".format(database_path))
            database_path = os.path.join(database_path, 'input')
            logging.info(
                "Loading RMG database instead from '{}'".format(database_path))
            rmg_database.load(
                database_path,
                kineticsFamilies=cls.possible_families,
                transportLibraries=[],
                reactionLibraries=[],
                seedMechanisms=[],
                thermoLibraries=[
                    'primaryThermoLibrary', 'thermo_DFT_CCSDTF12_BAC',
                    'CBS_QB3_1dHR'
                ],
                solvation=False,
            )

        cls.rmg_database = rmg_database

        cls.ts_databases = dict()
        for reaction_family in cls.possible_families:
            ts_database = TransitionStates()
            path = os.path.join(autotst.settings['tst_database_path'],
                                reaction_family)
            global_context = {'__builtins__': None}
            local_context = {'DistanceData': DistanceData}
            family = rmg_database.kinetics.families[reaction_family]
            ts_database.family = family
            ts_database.load(path, local_context, global_context)

            cls.ts_databases[reaction_family] = ts_database
コード例 #20
0
elif os.getenv('LSB_JOBINDEX'):
    i = int(os.getenv('LSB_JOBINDEX'))
else:
    raise Exception(
        "Specify a TS number!"
    )  # What does raise do? - Raises an error if we get to this part of the code.

rxnFamilies = [
    'H_Abstraction'
]  #, 'Disproportionation'] # I wonder why Disproportionation wasn't included? Too many errors?

print 'Loading RMG Database ...'
rmgDatabase = RMGDatabase()
rmgDatabase.load(
    os.path.abspath(
        os.path.join(os.getenv('RMGpy'), '..', 'RMG-database', 'input')),
    kineticsFamilies=rxnFamilies
)  #'default') # Loading the rmgDatabase for the reaction families given above
print 'Finished loading RMG Database ...'


def calculate(reaction):
    rxnFamily = reaction.family.label  # pulls the reaction family from the reaction
    tsDatabase = rmgDatabase.kinetics.families[
        rxnFamily].transitionStates  # pulls up transition states for a specific reaction family. I'm gonna look into RMG Database and see if this helps describe some things.
    # I don't understand this part comes from.
    reaction = qmCalc.getKineticData(
        reaction, tsDatabase
    )  # Performs rate reaction calculations on a given reaction with a specific transition state.

    for files in os.listdir('./'):  #removes the files specific to... what?
コード例 #21
0
# copy of this software and associated documentation files (the 'Software'),  #
# to deal in the Software without restriction, including without limitation   #
# the rights to use, copy, modify, merge, publish, distribute, sublicense,    #
# and/or sell copies of the Software, and to permit persons to whom the       #
# Software is furnished to do so, subject to the following conditions:        #
#                                                                             #
# The above copyright notice and this permission notice shall be included in  #
# all copies or substantial portions of the Software.                         #
#                                                                             #
# THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR  #
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,    #
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE #
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER      #
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING     #
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER         #
# DEALINGS IN THE SOFTWARE.                                                   #
#                                                                             #
###############################################################################

"""
This script machine writes all the families and groups (no libraries) so that RMG-database looks cleaner
and does not have duplicate indexes
"""

from rmgpy import settings
from rmgpy.data.rmg import RMGDatabase

database = RMGDatabase()
database.load(settings['database.directory'], kineticsFamilies = 'all')

database.save(settings['database.directory'])
コード例 #22
0
ファイル: uncertainty.py プロジェクト: PengZhang13/RMG-Py
class Uncertainty:
    """
    This class contains functions associated with running uncertainty analyses
    for a single RMG-generated mechanism.
    """

    def __init__(self, speciesList=None, reactionList=None, outputDirectory=''):
        """
        `speciesList`: list of RMG species objects
        `reactionList`: list of RMG reaction objects
        `outputDirectoy`: directory path for saving output files from the analyses
        """
        self.database = None
        self.speciesList = speciesList 
        self.reactionList = reactionList 
        self.speciesSourcesDict = None
        self.reactionSourcesDict = None
        self.allThermoSources = None
        self.allKineticSources = None
        self.thermoInputUncertainties = None
        self.kineticInputUncertainties = None
        self.outputDirectory = outputDirectory if outputDirectory else os.getcwd()
        
        # Make output directory if it does not yet exist:
        if not os.path.exists(self.outputDirectory):
            try:
                os.makedirs(self.outputDirectory)
            except:
                raise Exception('Uncertainty output directory could not be created.')
            
    def loadDatabase(self, kineticsFamilies='all',kineticsDepositories=None,thermoLibraries=None, reactionLibraries=None):
        """
        This function loads a single copy of the RMGDatabase with full verbose averaging
        of the rate rule to trace kinetics sources.  
        
        By default, this function loads all the kinetics families, only the training kinetics depository,
        the primaryThermoLibrary, and no reaction libraries.  
        """
        from rmgpy.data.rmg import RMGDatabase 
        from rmgpy import settings
        
        if not kineticsDepositories:
            kineticsDepositories = ['training']
        if not thermoLibraries:
            thermoLibraries = ['primaryThermoLibrary']
        if not reactionLibraries:
            reactionLibraries = []
            
            
        self.database = RMGDatabase()
        self.database.load(settings['database.directory'], 
                          kineticsFamilies=kineticsFamilies, 
                          kineticsDepositories=kineticsDepositories,
                          thermoLibraries=thermoLibraries,
                          reactionLibraries=reactionLibraries,
                          )
        
    
        # Prepare the database by loading training reactions but not averaging the rate rules
        for familyLabel, family in self.database.kinetics.families.iteritems():
            family.addKineticsRulesFromTrainingSet(thermoDatabase=self.database.thermo)
        
            family.fillKineticsRulesByAveragingUp(verbose=True)

    def loadModel(self, chemkinPath, dictionaryPath, transportPath=None):
        """
        Load a RMG-generated model into the Uncertainty class
        `chemkinPath`: path to the chem_annotated.inp CHEMKIN mechanism 
        `dictionaryPath`: path to the species_dictionary.txt file 
        `transportPath`: path to the tran.dat file (optional)

        Then create dictionaries stored in self.thermoGroups and self.rateRules
        containing information about the source of the thermodynamic and kinetic
        parameters
        """
        from rmgpy.chemkin import loadChemkinFile

        self.speciesList, self.reactionList = loadChemkinFile(chemkinPath,
                                                              dictionaryPath=dictionaryPath,
                                                              transportPath=transportPath)


    def extractSourcesFromModel(self):
        """
        Extract the source data from the model using its comments.
        Must be done after loading model and database to work.
        """
        self.speciesSourcesDict = {}
        for species in self.speciesList:
            source = self.database.thermo.extractSourceFromComments(species)
            
            # Now prep the source data
            # Do not alter the GAV information, but reassign QM and Library sources to the species indices that they came from
            if len(source.keys()) == 1:
                # The thermo came from a single source, so we know it comes from a value describing the exact species
                if 'Library' in source:
                    source['Library'] = self.speciesList.index(species)   # Use just the species index in self.speciesList, for better shorter printouts when debugging
                if 'QM' in source:
                    source['QM'] = self.speciesList.index(species)
                    
            elif len(source.keys()) == 2:
                # The thermo has two sources, which indicates it's an HBI correction on top of a library or QM value.  We must retrieve the original
                # saturated molecule's thermo instead of using the radical species as the source of thermo
                saturatedSpecies = retrieveSaturatedSpeciesFromList(species,self.speciesList)
                if 'Library' in source:
                    source['Library'] = self.speciesList.index(saturatedSpecies)
                if 'QM' in source:
                    source['QM'] = self.speciesList.index(saturatedSpecies)
            else:
                raise Exception('Source of thermo should not use more than two sources out of QM, Library, or GAV.')
            
            self.speciesSourcesDict[species] = source
        
        self.reactionSourcesDict = {}
        for reaction in self.reactionList:
            source = self.database.kinetics.extractSourceFromComments(reaction)
            # Prep the source data 
            # Consider any library or PDep reaction to be an independent parameter for now and assign the source to the index of the
            # reaction within self.reactionList
            if 'Library' in source:
                source['Library'] = self.reactionList.index(reaction)
            elif 'PDep' in source:
                source['PDep'] = self.reactionList.index(reaction)
            elif 'Training' in source:
                # Do nothing here because training source already saves the entry from the training reaction
                pass
            elif 'Rate Rules' in source:
                # Do nothing
                pass
            else:
                raise Exception('Source of kinetics must be either Library, PDep, Training, or Rate Rules')
            self.reactionSourcesDict[reaction] = source
        
        # Account for all the thermo sources
        allThermoSources = {'GAV':{}, 'Library':set(), 'QM':set()}
        for source in self.speciesSourcesDict.values():
            if 'GAV' in source:
                for groupType in source['GAV'].keys():
                    groupEntries = [groupTuple[0] for groupTuple in source['GAV'][groupType]]
                    if not groupType in allThermoSources['GAV']:
                        allThermoSources['GAV'][groupType] = set(groupEntries)
                    else:
                        allThermoSources['GAV'][groupType].update(groupEntries)
            if 'Library' in source:
                allThermoSources['Library'].add(source['Library'])  
            if 'QM' in source:
                allThermoSources['QM'].add(source['QM'])   

                
        # Convert to lists
        self.allThermoSources = {}
        self.allThermoSources['Library'] = list(allThermoSources['Library'])
        self.allThermoSources['QM'] = list(allThermoSources['QM'])
        self.allThermoSources['GAV'] = {}
        for groupType in allThermoSources['GAV'].keys():
            self.allThermoSources['GAV'][groupType] = list(allThermoSources['GAV'][groupType])
                
        # Account for all the kinetics sources
        allKineticSources = {'Rate Rules':{}, 'Training':{}, 'Library':[], 'PDep':[]}
        for source in self.reactionSourcesDict.values():
            if 'Training' in source:
                familyLabel = source['Training'][0]
                trainingEntry = source['Training'][1]
                if not familyLabel in allKineticSources['Training']:
                    allKineticSources['Training'][familyLabel] = set([trainingEntry])
                else:
                    allKineticSources['Training'][familyLabel].add(trainingEntry)
            elif 'Library' in source:
                allKineticSources['Library'].append(source['Library'])
            elif 'PDep' in source:
                allKineticSources['PDep'].append(source['PDep'])
            elif 'Rate Rules' in source:
                familyLabel = source['Rate Rules'][0]
                sourceDict = source['Rate Rules'][1]
                rules = sourceDict['rules']
                training = sourceDict['training']
                if rules:
                    ruleEntries = [ruleTuple[0] for ruleTuple in rules]
                    if not familyLabel in allKineticSources['Rate Rules']:
                        allKineticSources['Rate Rules'][familyLabel] = set(ruleEntries)
                    else:
                        allKineticSources['Rate Rules'][familyLabel].update(ruleEntries)
                if training:
                    # Even though they are from training reactions, we consider the rate rules derived from the training
                    # reactions to be noncorrelated, due to the fact that some may be reversed.
                    trainingRules = [trainingTuple[0] for trainingTuple in training]  # Pick the rate rule entries
                    if not familyLabel in allKineticSources['Rate Rules']:
                        allKineticSources['Rate Rules'][familyLabel] = set(trainingRules)
                    else:
                        allKineticSources['Rate Rules'][familyLabel].update(trainingRules)
        
        self.allKineticSources = {}
        self.allKineticSources['Library'] = allKineticSources['Library']
        self.allKineticSources['PDep'] = allKineticSources['PDep']
        # Convert to lists
        self.allKineticSources['Rate Rules'] = {}
        for familyLabel in allKineticSources['Rate Rules'].keys():
            self.allKineticSources['Rate Rules'][familyLabel] = list(allKineticSources['Rate Rules'][familyLabel])
            
        self.allKineticSources['Training'] = {}
        for familyLabel in allKineticSources['Training'].keys():
            self.allKineticSources['Training'][familyLabel] = list(allKineticSources['Training'][familyLabel])
    
    def assignParameterUncertainties(self, gParamEngine = ThermoParameterUncertainty(), kParamEngine = KineticParameterUncertainty()):
        """
        Assign uncertainties based on the sources of the species thermo and reaction kinetics.
        """
        
        self.thermoInputUncertainties = []
        self.kineticInputUncertainties = []
        
        for species in self.speciesList:
            dG = gParamEngine.getUncertaintyValue(self.speciesSourcesDict[species])
            self.thermoInputUncertainties.append(dG)
        for reaction in self.reactionList:
            dlnk = kParamEngine.getUncertaintyValue(self.reactionSourcesDict[reaction])
            self.kineticInputUncertainties.append(dlnk)
コード例 #23
0
from rmgpy.data.rmg import RMGDatabase
from rmgpy.reaction import Reaction
from rmgpy.exceptions import UndeterminableKineticsError


source = ['Intra_R_Add_Endocyclic', 'Intra_R_Add_Exocyclic']
destination = ['Intra_R_Add_Polycyclic']
families = source + destination

databasePath = rmgpy.settings['database.directory']

database = RMGDatabase()
database.load(
    path=databasePath,
    thermoLibraries=[],
    reactionLibraries=[],
    seedMechanisms=[],
    kineticsFamilies=families,
    kineticsDepositories=['training']
    )


# Modified from addKineticsRulesFromTrainingSet

toMove = []


# Remove entries from source families
for label in source:
    family = database.kinetics.families[label]
    
    depository = family.getTrainingDepository()
コード例 #24
0
                outputFile.write('\n\n')


if __name__ == '__main__':

    databaseProjectRootPath = os.path.dirname(os.path.abspath(__file__))
    #Thermo stuff
    #     ThermoDatabase=ThermoDatabase()
    #     ThermoDatabase.load(path)
    #     ThermoDatabase.save(r'C:\RMG-database\input\thermo_test')
    #     ThermoDatabase.save(path)
    FullDatabase = RMGDatabase()
    #     path=r'C:\RMG-database\input\thermo'
    path = os.path.join(databaseProjectRootPath, 'input')
    #     FullDatabase.load(thermoLibraries=)
    FullDatabase.load(path, kineticsFamilies='all')
    checkFamilies(FullDatabase)
#     trialDir=r'C:\Users\User1\Dropbox\Research\RMG\kinetics\LeaveOneOut\test'
#     trialDir=r'C:\RMG-database\input_test'
#     family=FullDatabase.kinetics.families['Disproportionation']
#     entryKey='Y_1centerbirad;O_Cdrad'
#
#     test=getKineticsFromRules(family, entryKey)
#
#     print test.comment
#     print test

#     NISTExact(FullDatabase, trialDir)
#     countNodesAll(NISTDatabase, trialDir)
#     consistencyTest(FullDatabase)
#     LeaveOneOut(FullDatabase, trialDir)
コード例 #25
0
def loadDatabase():
    print 'Loading RMG database...'
    from rmgpy.data.rmg import RMGDatabase
    database = RMGDatabase()
    database.load('input')
    return database
コード例 #26
0
                data = kinetics,
                reference = entry0.reference,
                rank = entry0.rank,
                shortDesc = entry0.shortDesc,
                longDesc = entry0.longDesc,
                history = entry0.history,
            )

            # Add the new rate rule to the depository of rate rules
            rules.entries[entry.index] = entry
            
            index += 1
            
################################################################################

if __name__ == '__main__':

    oldPath = 'output/RMG_database'
    newPath = 'input'
    
    print 'Loading the new RMG-Py database...'
    database = RMGDatabase()
    database.load(newPath)
    
    print 'Constructing additional rate rules from kinetics depository...'
    for family in database.kinetics.groups:
        generateAdditionalRateRules(family, database)
    
    print 'Saving old RMG-Java database...'
    database.saveOld(oldPath)
コード例 #27
0
def loadDatabase():
    print 'Loading RMG database...'
    from rmgpy.data.rmg import RMGDatabase
    database = RMGDatabase()
    database.load(settings['database.directory'], kineticsFamilies='all', kineticsDepositories='all')
    return database
コード例 #28
0
if __name__ == '__main__':
    from rmgpy import settings

    # Create the data evaluation directory
    trialDir = os.path.join(settings['database.directory'], '..', 'testing',
                            'eval')
    if not os.path.exists(trialDir):
        os.makedirs(trialDir)

    print 'Loading the RMG database...'
    FullDatabase = RMGDatabase()
    FullDatabase.load(
        settings['database.directory'],
        kineticsFamilies='all',
        kineticsDepositories='all',
        thermoLibraries=[
            'primaryThermoLibrary'
        ],  # Use just the primary thermo library, which contains necessary small molecular thermo
        reactionLibraries=[],
    )

    # Prepare the database by loading training reactions but not averaging the rate rules
    for family in FullDatabase.kinetics.families.values():
        family.addKineticsRulesFromTrainingSet(
            thermoDatabase=FullDatabase.thermo)

    print '--------------------------------------------'
    print 'Obtaining statistics for the families...'
    obtainKineticsFamilyStatistics(FullDatabase, trialDir)

    print '--------------------------------------------'
コード例 #29
0
from rmgpy.qm.reaction import QMReaction
from rmgpy.qm.main import QMSettings
from rmgpy.qm.gaussian import GaussianTSM062X
from rmgpy.reaction import Reaction
from rmgpy.molecule import Molecule, Atom
from rmgpy.species import Species
from rmgpy.data.rmg import RMGDatabase
import os

database = RMGDatabase()
database.load(os.path.abspath(
    os.path.join(os.getenv('RMGpy'), '..', 'RMG-database', 'input')),
              kineticsFamilies=['Silylene_Insertion'],
              seedMechanisms=[],
              solvation=False)
tsDatabase = database.kinetics.families['Silylene_Insertion'].transitionStates


def fixLonePairMolecule(mol_string):
    """
    Fix an incorrect SMILES parsing for molecule that should have a lone pair
    We fix the first atom we encounter. Not sure what to do if there's more
    than one
    """
    if "(S)" in mol_string:
        smiles = mol_string.split("(S")[0]
        rmg_mol = Molecule().fromSMILES(smiles)
        for atom in rmg_mol.atoms:
            if atom.radicalElectrons >= 2:
                atom.radicalElectrons -= 2
                atom.lonePairs += 1
コード例 #30
0
ファイル: uncertainty.py プロジェクト: zach-youssef/RMG-Py
class Uncertainty:
    """
    This class contains functions associated with running uncertainty analyses
    for a single RMG-generated mechanism.
    """
    def __init__(self,
                 speciesList=None,
                 reactionList=None,
                 outputDirectory=''):
        """
        `speciesList`: list of RMG species objects
        `reactionList`: list of RMG reaction objects
        `outputDirectoy`: directory path for saving output files from the analyses
        """
        self.database = None
        self.speciesList = speciesList
        self.reactionList = reactionList
        self.speciesSourcesDict = None
        self.reactionSourcesDict = None
        self.allThermoSources = None
        self.allKineticSources = None
        self.thermoInputUncertainties = None
        self.kineticInputUncertainties = None
        self.outputDirectory = outputDirectory if outputDirectory else os.getcwd(
        )

        # Make output directory if it does not yet exist:
        if not os.path.exists(self.outputDirectory):
            try:
                os.makedirs(self.outputDirectory)
            except:
                raise Exception(
                    'Uncertainty output directory could not be created.')

    def loadDatabase(self,
                     kineticsFamilies='all',
                     kineticsDepositories=None,
                     thermoLibraries=None,
                     reactionLibraries=None):
        """
        This function loads a single copy of the RMGDatabase with full verbose averaging
        of the rate rule to trace kinetics sources.  
        
        By default, this function loads all the kinetics families, only the training kinetics depository,
        the primaryThermoLibrary, and no reaction libraries.  
        """
        from rmgpy.data.rmg import RMGDatabase
        from rmgpy import settings

        if not kineticsDepositories:
            kineticsDepositories = ['training']
        if not thermoLibraries:
            thermoLibraries = ['primaryThermoLibrary']
        if not reactionLibraries:
            reactionLibraries = []

        self.database = RMGDatabase()
        self.database.load(
            settings['database.directory'],
            kineticsFamilies=kineticsFamilies,
            kineticsDepositories=kineticsDepositories,
            thermoLibraries=thermoLibraries,
            reactionLibraries=reactionLibraries,
        )

        # Prepare the database by loading training reactions but not averaging the rate rules
        for familyLabel, family in self.database.kinetics.families.iteritems():
            family.addKineticsRulesFromTrainingSet(
                thermoDatabase=self.database.thermo)

            family.fillKineticsRulesByAveragingUp(verbose=True)

    def loadModel(self, chemkinPath, dictionaryPath, transportPath=None):
        """
        Load a RMG-generated model into the Uncertainty class
        `chemkinPath`: path to the chem_annotated.inp CHEMKIN mechanism 
        `dictionaryPath`: path to the species_dictionary.txt file 
        `transportPath`: path to the tran.dat file (optional)

        Then create dictionaries stored in self.thermoGroups and self.rateRules
        containing information about the source of the thermodynamic and kinetic
        parameters
        """
        from rmgpy.chemkin import loadChemkinFile

        self.speciesList, self.reactionList = loadChemkinFile(
            chemkinPath,
            dictionaryPath=dictionaryPath,
            transportPath=transportPath)

    def retrieveSaturatedSpeciesFromList(self, species):
        """
        Given a radical `species`, this function retrieves the saturated species objects from a list of species objects
        and returns the saturated species object along with a boolean that indicates if the species is not part of the model
        (True->not in the model, False->in the model)
        """

        molecule = species.molecule[0]
        assert molecule.isRadical(), "Method only valid for radicals."
        saturatedStruct = molecule.copy(deep=True)
        saturatedStruct.saturate_radicals()
        for otherSpecies in self.speciesList:
            if otherSpecies.isIsomorphic(saturatedStruct):
                return otherSpecies, False

        #couldn't find saturated species in the model, try libraries
        newSpc = Species(molecule=[saturatedStruct])
        thermo = self.database.thermo.getThermoDataFromLibraries(newSpc)

        if thermo is not None:
            newSpc.thermo = thermo
            self.speciesList.append(newSpc)
            return newSpc, True
        else:
            raise Exception(
                'Could not retrieve saturated species form of {0} from the species list'
                .format(species))

    def extractSourcesFromModel(self):
        """
        Extract the source data from the model using its comments.
        Must be done after loading model and database to work.
        """
        self.speciesSourcesDict = {}
        ignoreSpcs = []
        for species in self.speciesList:
            if not species in ignoreSpcs:
                source = self.database.thermo.extractSourceFromComments(
                    species)

                # Now prep the source data
                # Do not alter the GAV information, but reassign QM and Library sources to the species indices that they came from
                if len(source.keys()) == 1:
                    # The thermo came from a single source, so we know it comes from a value describing the exact species
                    if 'Library' in source:
                        source['Library'] = self.speciesList.index(
                            species
                        )  # Use just the species index in self.speciesList, for better shorter printouts when debugging
                    if 'QM' in source:
                        source['QM'] = self.speciesList.index(species)

                elif len(source.keys()) == 2:
                    # The thermo has two sources, which indicates it's an HBI correction on top of a library or QM value.  We must retrieve the original
                    # saturated molecule's thermo instead of using the radical species as the source of thermo
                    saturatedSpecies, ignoreSpc = self.retrieveSaturatedSpeciesFromList(
                        species)

                    if ignoreSpc:  #this is saturated species that isn't in the actual model
                        ignoreSpcs.append(saturatedSpecies)

                    if 'Library' in source:
                        source['Library'] = self.speciesList.index(
                            saturatedSpecies)
                    if 'QM' in source:
                        source['QM'] = self.speciesList.index(saturatedSpecies)
                else:
                    raise Exception(
                        'Source of thermo should not use more than two sources out of QM, Library, or GAV.'
                    )

                self.speciesSourcesDict[species] = source

        self.reactionSourcesDict = {}
        for reaction in self.reactionList:
            source = self.database.kinetics.extractSourceFromComments(reaction)
            # Prep the source data
            # Consider any library or PDep reaction to be an independent parameter for now and assign the source to the index of the
            # reaction within self.reactionList
            if 'Library' in source:
                source['Library'] = self.reactionList.index(reaction)
            elif 'PDep' in source:
                source['PDep'] = self.reactionList.index(reaction)
            elif 'Training' in source:
                # Do nothing here because training source already saves the entry from the training reaction
                pass
            elif 'Rate Rules' in source:
                # Do nothing
                pass
            else:
                raise Exception(
                    'Source of kinetics must be either Library, PDep, Training, or Rate Rules'
                )
            self.reactionSourcesDict[reaction] = source

        for spc in ignoreSpcs:
            self.speciesList.remove(spc)

    def compileAllSources(self):
        """
        Compile two dictionaries composed of all the thermo and kinetic sources.  Must
        be performed after extractSourcesFromModel function
        """
        # Account for all the thermo sources
        allThermoSources = {'GAV': {}, 'Library': set(), 'QM': set()}
        for source in self.speciesSourcesDict.values():
            if 'GAV' in source:
                for groupType in source['GAV'].keys():
                    groupEntries = [
                        groupTuple[0]
                        for groupTuple in source['GAV'][groupType]
                    ]
                    if not groupType in allThermoSources['GAV']:
                        allThermoSources['GAV'][groupType] = set(groupEntries)
                    else:
                        allThermoSources['GAV'][groupType].update(groupEntries)
            if 'Library' in source:
                allThermoSources['Library'].add(source['Library'])
            if 'QM' in source:
                allThermoSources['QM'].add(source['QM'])

        # Convert to lists
        self.allThermoSources = {}
        self.allThermoSources['Library'] = list(allThermoSources['Library'])
        self.allThermoSources['QM'] = list(allThermoSources['QM'])
        self.allThermoSources['GAV'] = {}
        for groupType in allThermoSources['GAV'].keys():
            self.allThermoSources['GAV'][groupType] = list(
                allThermoSources['GAV'][groupType])

        # Account for all the kinetics sources
        allKineticSources = {
            'Rate Rules': {},
            'Training': {},
            'Library': [],
            'PDep': []
        }
        for source in self.reactionSourcesDict.values():
            if 'Training' in source:
                familyLabel = source['Training'][0]
                trainingEntry = source['Training'][1]
                if not familyLabel in allKineticSources['Training']:
                    allKineticSources['Training'][familyLabel] = set(
                        [trainingEntry])
                else:
                    allKineticSources['Training'][familyLabel].add(
                        trainingEntry)
            elif 'Library' in source:
                allKineticSources['Library'].append(source['Library'])
            elif 'PDep' in source:
                allKineticSources['PDep'].append(source['PDep'])
            elif 'Rate Rules' in source:
                familyLabel = source['Rate Rules'][0]
                sourceDict = source['Rate Rules'][1]
                rules = sourceDict['rules']
                training = sourceDict['training']
                if rules:
                    ruleEntries = [ruleTuple[0] for ruleTuple in rules]
                    if not familyLabel in allKineticSources['Rate Rules']:
                        allKineticSources['Rate Rules'][familyLabel] = set(
                            ruleEntries)
                    else:
                        allKineticSources['Rate Rules'][familyLabel].update(
                            ruleEntries)
                if training:
                    # Even though they are from training reactions, we consider the rate rules derived from the training
                    # reactions to be noncorrelated, due to the fact that some may be reversed.
                    trainingRules = [
                        trainingTuple[0] for trainingTuple in training
                    ]  # Pick the rate rule entries
                    if not familyLabel in allKineticSources['Rate Rules']:
                        allKineticSources['Rate Rules'][familyLabel] = set(
                            trainingRules)
                    else:
                        allKineticSources['Rate Rules'][familyLabel].update(
                            trainingRules)

        self.allKineticSources = {}
        self.allKineticSources['Library'] = allKineticSources['Library']
        self.allKineticSources['PDep'] = allKineticSources['PDep']
        # Convert to lists
        self.allKineticSources['Rate Rules'] = {}
        for familyLabel in allKineticSources['Rate Rules'].keys():
            self.allKineticSources['Rate Rules'][familyLabel] = list(
                allKineticSources['Rate Rules'][familyLabel])

        self.allKineticSources['Training'] = {}
        for familyLabel in allKineticSources['Training'].keys():
            self.allKineticSources['Training'][familyLabel] = list(
                allKineticSources['Training'][familyLabel])

    def assignParameterUncertainties(
            self,
            gParamEngine=ThermoParameterUncertainty(),
            kParamEngine=KineticParameterUncertainty(),
            correlated=False):
        """
        Assign uncertainties based on the sources of the species thermo and reaction kinetics.
        """

        self.thermoInputUncertainties = []
        self.kineticInputUncertainties = []

        for species in self.speciesList:
            if not correlated:
                dG = gParamEngine.getUncertaintyValue(
                    self.speciesSourcesDict[species])
                self.thermoInputUncertainties.append(dG)
            else:
                source = self.speciesSourcesDict[species]
                dG = {}
                if 'Library' in source:
                    pdG = gParamEngine.getPartialUncertaintyValue(
                        source, 'Library', corrParam=source['Library'])
                    label = 'Library {}'.format(
                        self.speciesList[source['Library']].toChemkin())
                    dG[label] = pdG
                if 'QM' in source:
                    pdG = gParamEngine.getPartialUncertaintyValue(
                        source, 'QM', corrParam=source['QM'])
                    label = 'QM {}'.format(
                        self.speciesList[source['QM']].toChemkin())
                    dG[label] = pdG
                if 'GAV' in source:
                    for groupType, groupList in source['GAV'].iteritems():
                        for group, weight in groupList:
                            pdG = gParamEngine.getPartialUncertaintyValue(
                                source, 'GAV', group, groupType)
                            label = 'Group({}) {}'.format(
                                groupType, group.label)
                            dG[label] = pdG
                    # We also know if there is group additivity used, there will be uncorrelated estimation error
                    est_pdG = gParamEngine.getPartialUncertaintyValue(
                        source, 'Estimation')
                    if est_pdG:
                        label = 'Estimation {}'.format(species.toChemkin())
                        dG[label] = est_pdG
                self.thermoInputUncertainties.append(dG)

        for reaction in self.reactionList:
            if not correlated:
                dlnk = kParamEngine.getUncertaintyValue(
                    self.reactionSourcesDict[reaction])
                self.kineticInputUncertainties.append(dlnk)
            else:
                source = self.reactionSourcesDict[reaction]
                dlnk = {}
                if 'Rate Rules' in source:
                    family = source['Rate Rules'][0]
                    sourceDict = source['Rate Rules'][1]
                    rules = sourceDict['rules']
                    training = sourceDict['training']
                    for ruleEntry, weight in rules:
                        dplnk = kParamEngine.getPartialUncertaintyValue(
                            source,
                            'Rate Rules',
                            corrParam=ruleEntry,
                            corrFamily=family)
                        label = '{} {}'.format(family, ruleEntry)
                        dlnk[label] = dplnk

                    for ruleEntry, trainingEntry, weight in training:
                        dplnk = kParamEngine.getPartialUncertaintyValue(
                            source,
                            'Rate Rules',
                            corrParam=ruleEntry,
                            corrFamily=family)
                        label = '{} {}'.format(family, ruleEntry)
                        dlnk[label] = dplnk

                    # There is also estimation error if rate rules are used
                    est_dplnk = kParamEngine.getPartialUncertaintyValue(
                        source, 'Estimation')
                    if est_dplnk:
                        label = 'Estimation {}'.format(
                            reaction.toChemkin(self.speciesList,
                                               kinetics=False))
                        dlnk[label] = est_dplnk

                elif 'PDep' in source:
                    dplnk = kParamEngine.getPartialUncertaintyValue(
                        source, 'PDep', source['PDep'])
                    label = 'PDep {}'.format(
                        reaction.toChemkin(self.speciesList, kinetics=False))
                    dlnk[label] = dplnk

                elif 'Library' in source:
                    dplnk = kParamEngine.getPartialUncertaintyValue(
                        source, 'Library', source['Library'])
                    label = 'Library {}'.format(
                        reaction.toChemkin(self.speciesList, kinetics=False))
                    dlnk[label] = dplnk

                elif 'Training' in source:
                    dplnk = kParamEngine.getPartialUncertaintyValue(
                        source, 'Training', source['Training'])
                    family = source['Training'][0]
                    label = 'Training {} {}'.format(
                        family,
                        reaction.toChemkin(self.speciesList, kinetics=False))
                    dlnk[label] = dplnk

                self.kineticInputUncertainties.append(dlnk)

    def sensitivityAnalysis(self,
                            initialMoleFractions,
                            sensitiveSpecies,
                            T,
                            P,
                            terminationTime,
                            sensitivityThreshold=1e-3,
                            number=10,
                            fileformat='.png'):
        """
        Run sensitivity analysis using the RMG solver in a single ReactionSystem object
        
        initialMoleFractions is a dictionary with Species objects as keys and mole fraction initial conditions
        sensitiveSpecies is a list of sensitive Species objects
        number is the number of top species thermo or reaction kinetics desired to be plotted
        """

        from rmgpy.solver import SimpleReactor, TerminationTime
        from rmgpy.quantity import Quantity
        from rmgpy.tools.simulate import plot_sensitivity
        from rmgpy.rmg.listener import SimulationProfileWriter, SimulationProfilePlotter
        from rmgpy.rmg.settings import ModelSettings, SimulatorSettings
        T = Quantity(T)
        P = Quantity(P)
        termination = [TerminationTime(Quantity(terminationTime))]

        reactionSystem = SimpleReactor(T, P, initialMoleFractions, termination,
                                       sensitiveSpecies, sensitivityThreshold)

        # Create the csv worksheets for logging sensitivity
        util.makeOutputSubdirectory(self.outputDirectory, 'solver')
        sensWorksheet = []
        reactionSystemIndex = 0
        for spec in reactionSystem.sensitiveSpecies:
            csvfilePath = os.path.join(
                self.outputDirectory, 'solver',
                'sensitivity_{0}_SPC_{1}.csv'.format(reactionSystemIndex + 1,
                                                     spec.index))
            sensWorksheet.append(csvfilePath)

        reactionSystem.attach(
            SimulationProfileWriter(self.outputDirectory, reactionSystemIndex,
                                    self.speciesList))
        reactionSystem.attach(
            SimulationProfilePlotter(self.outputDirectory, reactionSystemIndex,
                                     self.speciesList))

        simulatorSettings = SimulatorSettings()  #defaults

        modelSettings = ModelSettings()  #defaults
        modelSettings.fluxToleranceMoveToCore = 0.1
        modelSettings.fluxToleranceInterrupt = 1.0
        modelSettings.fluxToleranceKeepInEdge = 0.0

        reactionSystem.simulate(
            coreSpecies=self.speciesList,
            coreReactions=self.reactionList,
            edgeSpecies=[],
            edgeReactions=[],
            surfaceSpecies=[],
            surfaceReactions=[],
            modelSettings=modelSettings,
            simulatorSettings=simulatorSettings,
            sensitivity=True,
            sensWorksheet=sensWorksheet,
        )

        plot_sensitivity(self.outputDirectory,
                         reactionSystemIndex,
                         reactionSystem.sensitiveSpecies,
                         number=number,
                         fileformat=fileformat)

    def localAnalysis(self,
                      sensitiveSpecies,
                      correlated=False,
                      number=10,
                      fileformat='.png'):
        """
        Conduct local uncertainty analysis on the reaction model.
        sensitiveSpecies is a list of sensitive Species objects
        number is the number of highest contributing uncertain parameters desired to be plotted
        fileformat can be either .png, .pdf, or .svg
        """
        for sensSpecies in sensitiveSpecies:
            csvfilePath = os.path.join(
                self.outputDirectory, 'solver',
                'sensitivity_{0}_SPC_{1}.csv'.format(1, sensSpecies.index))
            time, dataList = parseCSVData(csvfilePath)
            # Assign uncertainties
            thermoDataList = []
            reactionDataList = []
            for data in dataList:
                if data.species:
                    for species in self.speciesList:
                        if species.toChemkin() == data.species:
                            index = self.speciesList.index(species)
                            break
                    else:
                        raise Exception(
                            'Chemkin name {} of species in the CSV file does not match anything in the species list.'
                            .format(data.species))

                    data.uncertainty = self.thermoInputUncertainties[index]
                    thermoDataList.append(data)

                if data.reaction:
                    rxnIndex = int(data.index) - 1
                    data.uncertainty = self.kineticInputUncertainties[rxnIndex]
                    reactionDataList.append(data)

            if correlated:
                correlatedThermoData = {}
                correlatedReactionData = {}
                for data in thermoDataList:
                    for label, dpG in data.uncertainty.iteritems():
                        if label in correlatedThermoData:
                            # Unpack the labels and partial uncertainties
                            correlatedThermoData[label].data[-1] += data.data[
                                -1] * dpG  # Multiply the sensitivity with the partial uncertainty
                        else:
                            correlatedThermoData[label] = GenericData(
                                data=[data.data[-1] * dpG],
                                uncertainty=1,
                                label=label,
                                species='dummy')
                for data in reactionDataList:
                    for label, dplnk in data.uncertainty.iteritems():
                        if label in correlatedReactionData:
                            correlatedReactionData[label].data[
                                -1] += data.data[-1] * dplnk
                        else:
                            correlatedReactionData[label] = GenericData(
                                data=[data.data[-1] * dplnk],
                                uncertainty=1,
                                label=label,
                                reaction='dummy')

                thermoDataList = correlatedThermoData.values()
                reactionDataList = correlatedReactionData.values()

            # Compute total variance
            totalVariance = 0.0
            for data in thermoDataList:
                totalVariance += (data.data[-1] * data.uncertainty)**2
            for data in reactionDataList:
                totalVariance += (data.data[-1] * data.uncertainty)**2

            if not correlated:
                # Add the reaction index to the data label of the reaction uncertainties
                for data in reactionDataList:
                    data.label = 'k' + str(
                        data.index) + ': ' + data.label.split()[-1]

            thermoUncertaintyPlotPath = os.path.join(
                self.outputDirectory,
                'thermoLocalUncertainty_{0}'.format(sensSpecies.toChemkin()) +
                fileformat)
            reactionUncertaintyPlotPath = os.path.join(
                self.outputDirectory, 'kineticsLocalUncertainty_{0}'.format(
                    sensSpecies.toChemkin()) + fileformat)
            ReactionSensitivityPlot(xVar=time,
                                    yVar=reactionDataList,
                                    numReactions=number).uncertaintyPlot(
                                        totalVariance,
                                        filename=reactionUncertaintyPlotPath)
            ThermoSensitivityPlot(xVar=time,
                                  yVar=thermoDataList,
                                  numSpecies=number).uncertaintyPlot(
                                      totalVariance,
                                      filename=thermoUncertaintyPlotPath)
コード例 #31
0
class Uncertainty:
    """
    This class contains functions associated with running uncertainty analyses
    for a single RMG-generated mechanism.
    """

    def __init__(self, speciesList=None, reactionList=None, outputDirectory=''):
        """
        `speciesList`: list of RMG species objects
        `reactionList`: list of RMG reaction objects
        `outputDirectoy`: directory path for saving output files from the analyses
        """
        self.database = None
        self.speciesList = speciesList 
        self.reactionList = reactionList 
        self.speciesSourcesDict = None
        self.reactionSourcesDict = None
        self.allThermoSources = None
        self.allKineticSources = None
        self.thermoInputUncertainties = None
        self.kineticInputUncertainties = None
        self.outputDirectory = outputDirectory if outputDirectory else os.getcwd()
        
        # Make output directory if it does not yet exist:
        if not os.path.exists(self.outputDirectory):
            try:
                os.makedirs(self.outputDirectory)
            except:
                raise Exception('Uncertainty output directory could not be created.')
            
    def loadDatabase(self, kineticsFamilies='all',kineticsDepositories=None,thermoLibraries=None, reactionLibraries=None):
        """
        This function loads a single copy of the RMGDatabase with full verbose averaging
        of the rate rule to trace kinetics sources.  
        
        By default, this function loads all the kinetics families, only the training kinetics depository,
        the primaryThermoLibrary, and no reaction libraries.  
        """
        from rmgpy.data.rmg import RMGDatabase 
        from rmgpy import settings
        
        if not kineticsDepositories:
            kineticsDepositories = ['training']
        if not thermoLibraries:
            thermoLibraries = ['primaryThermoLibrary']
        if not reactionLibraries:
            reactionLibraries = []
            
            
        self.database = RMGDatabase()
        self.database.load(settings['database.directory'], 
                          kineticsFamilies=kineticsFamilies, 
                          kineticsDepositories=kineticsDepositories,
                          thermoLibraries=thermoLibraries,
                          reactionLibraries=reactionLibraries,
                          )
        
    
        # Prepare the database by loading training reactions but not averaging the rate rules
        for familyLabel, family in self.database.kinetics.families.iteritems():
            family.addKineticsRulesFromTrainingSet(thermoDatabase=self.database.thermo)
        
            family.fillKineticsRulesByAveragingUp(verbose=True)

    def loadModel(self, chemkinPath, dictionaryPath, transportPath=None):
        """
        Load a RMG-generated model into the Uncertainty class
        `chemkinPath`: path to the chem_annotated.inp CHEMKIN mechanism 
        `dictionaryPath`: path to the species_dictionary.txt file 
        `transportPath`: path to the tran.dat file (optional)

        Then create dictionaries stored in self.thermoGroups and self.rateRules
        containing information about the source of the thermodynamic and kinetic
        parameters
        """
        from rmgpy.chemkin import loadChemkinFile

        self.speciesList, self.reactionList = loadChemkinFile(chemkinPath,
                                                              dictionaryPath=dictionaryPath,
                                                              transportPath=transportPath)

    def retrieveSaturatedSpeciesFromList(self,species):
        """
        Given a radical `species`, this function retrieves the saturated species objects from a list of species objects
        and returns the saturated species object along with a boolean that indicates if the species is not part of the model
        (True->not in the model, False->in the model)
        """
        
        molecule = species.molecule[0]
        assert molecule.isRadical(), "Method only valid for radicals."
        saturatedStruct = molecule.copy(deep=True)
        saturatedStruct.saturate_radicals()
        for otherSpecies in self.speciesList:
            if otherSpecies.isIsomorphic(saturatedStruct):
                return otherSpecies, False
        
        #couldn't find saturated species in the model, try libraries
        newSpc = Species(molecule=[saturatedStruct])
        thermo = self.database.thermo.getThermoDataFromLibraries(newSpc)
        
        if thermo is not None:
            newSpc.thermo = thermo
            self.speciesList.append(newSpc)
            return newSpc, True
        else:         
            raise Exception('Could not retrieve saturated species form of {0} from the species list'.format(species))

    def extractSourcesFromModel(self):
        """
        Extract the source data from the model using its comments.
        Must be done after loading model and database to work.
        """
        self.speciesSourcesDict = {}
        ignoreSpcs = []
        for species in self.speciesList:
            if not species in ignoreSpcs:
                source = self.database.thermo.extractSourceFromComments(species)
            
                # Now prep the source data
                # Do not alter the GAV information, but reassign QM and Library sources to the species indices that they came from
                if len(source.keys()) == 1:
                    # The thermo came from a single source, so we know it comes from a value describing the exact species
                    if 'Library' in source:
                        source['Library'] = self.speciesList.index(species)   # Use just the species index in self.speciesList, for better shorter printouts when debugging
                    if 'QM' in source:
                        source['QM'] = self.speciesList.index(species)
                        
                elif len(source.keys()) == 2:
                    # The thermo has two sources, which indicates it's an HBI correction on top of a library or QM value.  We must retrieve the original
                    # saturated molecule's thermo instead of using the radical species as the source of thermo
                    saturatedSpecies,ignoreSpc = self.retrieveSaturatedSpeciesFromList(species)
                    
                    if ignoreSpc: #this is saturated species that isn't in the actual model
                        ignoreSpcs.append(saturatedSpecies)
                        
                    if 'Library' in source:
                        source['Library'] = self.speciesList.index(saturatedSpecies)
                    if 'QM' in source:
                        source['QM'] = self.speciesList.index(saturatedSpecies)
                else:
                    raise Exception('Source of thermo should not use more than two sources out of QM, Library, or GAV.')
                
                self.speciesSourcesDict[species] = source
        
        self.reactionSourcesDict = {}
        for reaction in self.reactionList:
            source = self.database.kinetics.extractSourceFromComments(reaction)
            # Prep the source data 
            # Consider any library or PDep reaction to be an independent parameter for now and assign the source to the index of the
            # reaction within self.reactionList
            if 'Library' in source:
                source['Library'] = self.reactionList.index(reaction)
            elif 'PDep' in source:
                source['PDep'] = self.reactionList.index(reaction)
            elif 'Training' in source:
                # Do nothing here because training source already saves the entry from the training reaction
                pass
            elif 'Rate Rules' in source:
                # Do nothing
                pass
            else:
                raise Exception('Source of kinetics must be either Library, PDep, Training, or Rate Rules')
            self.reactionSourcesDict[reaction] = source
        
        for spc in ignoreSpcs:
            self.speciesList.remove(spc)
            
    def compileAllSources(self):
        """
        Compile two dictionaries composed of all the thermo and kinetic sources.  Must
        be performed after extractSourcesFromModel function
        """
        # Account for all the thermo sources
        allThermoSources = {'GAV':{}, 'Library':set(), 'QM':set()}
        for source in self.speciesSourcesDict.values():
            if 'GAV' in source:
                for groupType in source['GAV'].keys():
                    groupEntries = [groupTuple[0] for groupTuple in source['GAV'][groupType]]
                    if not groupType in allThermoSources['GAV']:
                        allThermoSources['GAV'][groupType] = set(groupEntries)
                    else:
                        allThermoSources['GAV'][groupType].update(groupEntries)
            if 'Library' in source:
                allThermoSources['Library'].add(source['Library'])  
            if 'QM' in source:
                allThermoSources['QM'].add(source['QM'])   

                
        # Convert to lists
        self.allThermoSources = {}
        self.allThermoSources['Library'] = list(allThermoSources['Library'])
        self.allThermoSources['QM'] = list(allThermoSources['QM'])
        self.allThermoSources['GAV'] = {}
        for groupType in allThermoSources['GAV'].keys():
            self.allThermoSources['GAV'][groupType] = list(allThermoSources['GAV'][groupType])
                
        # Account for all the kinetics sources
        allKineticSources = {'Rate Rules':{}, 'Training':{}, 'Library':[], 'PDep':[]}
        for source in self.reactionSourcesDict.values():
            if 'Training' in source:
                familyLabel = source['Training'][0]
                trainingEntry = source['Training'][1]
                if not familyLabel in allKineticSources['Training']:
                    allKineticSources['Training'][familyLabel] = set([trainingEntry])
                else:
                    allKineticSources['Training'][familyLabel].add(trainingEntry)
            elif 'Library' in source:
                allKineticSources['Library'].append(source['Library'])
            elif 'PDep' in source:
                allKineticSources['PDep'].append(source['PDep'])
            elif 'Rate Rules' in source:
                familyLabel = source['Rate Rules'][0]
                sourceDict = source['Rate Rules'][1]
                rules = sourceDict['rules']
                training = sourceDict['training']
                if rules:
                    ruleEntries = [ruleTuple[0] for ruleTuple in rules]
                    if not familyLabel in allKineticSources['Rate Rules']:
                        allKineticSources['Rate Rules'][familyLabel] = set(ruleEntries)
                    else:
                        allKineticSources['Rate Rules'][familyLabel].update(ruleEntries)
                if training:
                    # Even though they are from training reactions, we consider the rate rules derived from the training
                    # reactions to be noncorrelated, due to the fact that some may be reversed.
                    trainingRules = [trainingTuple[0] for trainingTuple in training]  # Pick the rate rule entries
                    if not familyLabel in allKineticSources['Rate Rules']:
                        allKineticSources['Rate Rules'][familyLabel] = set(trainingRules)
                    else:
                        allKineticSources['Rate Rules'][familyLabel].update(trainingRules)
        
        self.allKineticSources = {}
        self.allKineticSources['Library'] = allKineticSources['Library']
        self.allKineticSources['PDep'] = allKineticSources['PDep']
        # Convert to lists
        self.allKineticSources['Rate Rules'] = {}
        for familyLabel in allKineticSources['Rate Rules'].keys():
            self.allKineticSources['Rate Rules'][familyLabel] = list(allKineticSources['Rate Rules'][familyLabel])
            
        self.allKineticSources['Training'] = {}
        for familyLabel in allKineticSources['Training'].keys():
            self.allKineticSources['Training'][familyLabel] = list(allKineticSources['Training'][familyLabel])
    
    def assignParameterUncertainties(self, gParamEngine = ThermoParameterUncertainty(), kParamEngine = KineticParameterUncertainty(), correlated=False):
        """
        Assign uncertainties based on the sources of the species thermo and reaction kinetics.
        """
        
        self.thermoInputUncertainties = []
        self.kineticInputUncertainties = []

        
        for species in self.speciesList:
            if not correlated:
                dG = gParamEngine.getUncertaintyValue(self.speciesSourcesDict[species])
                self.thermoInputUncertainties.append(dG)
            else:
                source = self.speciesSourcesDict[species]
                dG = {}
                if 'Library' in source:
                    pdG = gParamEngine.getPartialUncertaintyValue(source, 'Library', corrParam=source['Library'])
                    label = 'Library {}'.format(self.speciesList[source['Library']].toChemkin())
                    dG[label] = pdG
                if 'QM' in source:
                    pdG = gParamEngine.getPartialUncertaintyValue(source, 'QM',corrParam=source['QM'])
                    label = 'QM {}'.format(self.speciesList[source['QM']].toChemkin())
                    dG[label] = pdG
                if 'GAV' in source:
                    for groupType, groupList in source['GAV'].iteritems():
                        for group, weight in groupList:
                            pdG = gParamEngine.getPartialUncertaintyValue(source, 'GAV', group, groupType)
                            label = 'Group({}) {}'.format(groupType, group.label)
                            dG[label] = pdG
                    # We also know if there is group additivity used, there will be uncorrelated estimation error
                    est_pdG = gParamEngine.getPartialUncertaintyValue(source, 'Estimation')
                    if est_pdG: 
                        label = 'Estimation {}'.format(species.toChemkin())
                        dG[label] = est_pdG
                self.thermoInputUncertainties.append(dG)


        for reaction in self.reactionList:
            if not correlated:
                dlnk = kParamEngine.getUncertaintyValue(self.reactionSourcesDict[reaction])
                self.kineticInputUncertainties.append(dlnk)
            else:
                source = self.reactionSourcesDict[reaction]
                dlnk = {}
                if 'Rate Rules' in source:
                    family = source['Rate Rules'][0]
                    sourceDict = source['Rate Rules'][1]
                    rules = sourceDict['rules']
                    training = sourceDict['training']
                    for ruleEntry, weight in rules:
                        dplnk = kParamEngine.getPartialUncertaintyValue(source, 'Rate Rules', corrParam=ruleEntry, corrFamily=family)
                        label = '{} {}'.format(family, ruleEntry)
                        dlnk[label]=dplnk

                    for ruleEntry, trainingEntry, weight in training:
                        dplnk = kParamEngine.getPartialUncertaintyValue(source, 'Rate Rules', corrParam=ruleEntry, corrFamily=family)
                        label = '{} {}'.format(family, ruleEntry)
                        dlnk[label]=dplnk

                    # There is also estimation error if rate rules are used
                    est_dplnk = kParamEngine.getPartialUncertaintyValue(source, 'Estimation')
                    if est_dplnk:
                        label = 'Estimation {}'.format(reaction.toChemkin(self.speciesList, kinetics=False))
                        dlnk[label]=est_dplnk

                elif 'PDep' in source:
                    dplnk = kParamEngine.getPartialUncertaintyValue(source, 'PDep', source['PDep'])
                    label = 'PDep {}'.format(reaction.toChemkin(self.speciesList, kinetics=False))
                    dlnk[label]=dplnk

                elif 'Library' in source:
                    dplnk = kParamEngine.getPartialUncertaintyValue(source, 'Library', source['Library'])
                    label = 'Library {}'.format(reaction.toChemkin(self.speciesList, kinetics=False))
                    dlnk[label]=dplnk

                elif 'Training' in source:
                    dplnk = kParamEngine.getPartialUncertaintyValue(source, 'Training', source['Training'])
                    family = source['Training'][0]
                    label = 'Training {} {}'.format(family, reaction.toChemkin(self.speciesList, kinetics=False))
                    dlnk[label]=dplnk
                
                self.kineticInputUncertainties.append(dlnk)

    def sensitivityAnalysis(self, initialMoleFractions, sensitiveSpecies, T, P, terminationTime, sensitivityThreshold=1e-3, number=10, fileformat='.png'):
        """
        Run sensitivity analysis using the RMG solver in a single ReactionSystem object
        
        initialMoleFractions is a dictionary with Species objects as keys and mole fraction initial conditions
        sensitiveSpecies is a list of sensitive Species objects
        number is the number of top species thermo or reaction kinetics desired to be plotted
        """
        
        
        from rmgpy.solver import SimpleReactor, TerminationTime
        from rmgpy.quantity import Quantity
        from rmgpy.tools.simulate import plot_sensitivity
        from rmgpy.rmg.listener import SimulationProfileWriter, SimulationProfilePlotter
        from rmgpy.rmg.settings import ModelSettings, SimulatorSettings
        T = Quantity(T)
        P = Quantity(P)
        termination=[TerminationTime(Quantity(terminationTime))]
                                     
        reactionSystem = SimpleReactor(T=T,
                                       P=P,
                                       initialMoleFractions=initialMoleFractions,
                                       termination=termination,
                                       sensitiveSpecies=sensitiveSpecies,
                                       sensitivityThreshold=sensitivityThreshold)
        
        # Create the csv worksheets for logging sensitivity
        util.makeOutputSubdirectory(self.outputDirectory, 'solver')
        sensWorksheet = []
        reactionSystemIndex = 0
        for spec in reactionSystem.sensitiveSpecies:
            csvfilePath = os.path.join(self.outputDirectory, 'solver', 'sensitivity_{0}_SPC_{1}.csv'.format(reactionSystemIndex+1, spec.index))
            sensWorksheet.append(csvfilePath)

        reactionSystem.attach(SimulationProfileWriter(
            self.outputDirectory, reactionSystemIndex, self.speciesList))  
        reactionSystem.attach(SimulationProfilePlotter(
            self.outputDirectory, reactionSystemIndex, self.speciesList))
        
        simulatorSettings = SimulatorSettings() #defaults
        
        modelSettings = ModelSettings() #defaults
        modelSettings.fluxToleranceMoveToCore = 0.1
        modelSettings.fluxToleranceInterrupt = 1.0
        modelSettings.fluxToleranceKeepInEdge = 0.0
        
        reactionSystem.simulate(
            coreSpecies = self.speciesList,
            coreReactions = self.reactionList,
            edgeSpecies = [],
            edgeReactions = [],
            surfaceSpecies = [],
            surfaceReactions = [],
            modelSettings = modelSettings,
            simulatorSettings = simulatorSettings,
            sensitivity = True,
            sensWorksheet = sensWorksheet,
        )
        
        
        plot_sensitivity(self.outputDirectory, reactionSystemIndex, reactionSystem.sensitiveSpecies, number=number, fileformat=fileformat)
    
    def localAnalysis(self, sensitiveSpecies, correlated=False, number=10, fileformat='.png'):
        """
        Conduct local uncertainty analysis on the reaction model.
        sensitiveSpecies is a list of sensitive Species objects
        number is the number of highest contributing uncertain parameters desired to be plotted
        fileformat can be either .png, .pdf, or .svg
        """
        for sensSpecies in sensitiveSpecies:
            csvfilePath = os.path.join(self.outputDirectory, 'solver', 'sensitivity_{0}_SPC_{1}.csv'.format(1, sensSpecies.index))
            time, dataList = parseCSVData(csvfilePath)
            # Assign uncertainties
            thermoDataList = []
            reactionDataList = []
            for data in dataList:
                if data.species:
                    for species in self.speciesList:
                        if species.toChemkin() == data.species:
                            index = self.speciesList.index(species)
                            break
                    else:
                        raise Exception('Chemkin name {} of species in the CSV file does not match anything in the species list.'.format(data.species))
                    
                    data.uncertainty = self.thermoInputUncertainties[index]
                    thermoDataList.append(data)


                if data.reaction:
                    rxnIndex = int(data.index) - 1
                    data.uncertainty = self.kineticInputUncertainties[rxnIndex]
                    reactionDataList.append(data)


            if correlated:
                correlatedThermoData = {}
                correlatedReactionData = {}
                for data in thermoDataList:
                    for label, dpG in data.uncertainty.iteritems():
                        if label in correlatedThermoData:
                            # Unpack the labels and partial uncertainties
                            correlatedThermoData[label].data[-1] += data.data[-1]*dpG   # Multiply the sensitivity with the partial uncertainty
                        else:
                            correlatedThermoData[label] = GenericData(data=[data.data[-1]*dpG], uncertainty=1, label=label, species='dummy')
                for data in reactionDataList:
                    for label, dplnk in data.uncertainty.iteritems():
                        if label in correlatedReactionData:
                            correlatedReactionData[label].data[-1] += data.data[-1]*dplnk
                        else:
                            correlatedReactionData[label] = GenericData(data=[data.data[-1]*dplnk], uncertainty=1, label=label, reaction='dummy')

                thermoDataList = correlatedThermoData.values()
                reactionDataList = correlatedReactionData.values()

            # Compute total variance
            totalVariance = 0.0
            for data in thermoDataList:
                totalVariance += (data.data[-1]*data.uncertainty)**2
            for data in reactionDataList:
                totalVariance += (data.data[-1]*data.uncertainty)**2

            if not correlated:
                # Add the reaction index to the data label of the reaction uncertainties
                for data in reactionDataList:
                    data.label = 'k'+str(data.index) + ': ' + data.label.split()[-1]
            
            thermoUncertaintyPlotPath = os.path.join(self.outputDirectory, 'thermoLocalUncertainty_{0}'.format(sensSpecies.toChemkin()) + fileformat)
            reactionUncertaintyPlotPath = os.path.join(self.outputDirectory, 'kineticsLocalUncertainty_{0}'.format(sensSpecies.toChemkin()) + fileformat)
            ReactionSensitivityPlot(xVar=time,yVar=reactionDataList,numReactions=number).uncertaintyPlot(totalVariance, filename=reactionUncertaintyPlotPath)
            ThermoSensitivityPlot(xVar=time,yVar=thermoDataList,numSpecies=number).uncertaintyPlot(totalVariance, filename=thermoUncertaintyPlotPath)
コード例 #32
0
# copy of this software and associated documentation files (the 'Software'),  #
# to deal in the Software without restriction, including without limitation   #
# the rights to use, copy, modify, merge, publish, distribute, sublicense,    #
# and/or sell copies of the Software, and to permit persons to whom the       #
# Software is furnished to do so, subject to the following conditions:        #
#                                                                             #
# The above copyright notice and this permission notice shall be included in  #
# all copies or substantial portions of the Software.                         #
#                                                                             #
# THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR  #
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,    #
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE #
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER      #
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING     #
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER         #
# DEALINGS IN THE SOFTWARE.                                                   #
#                                                                             #
###############################################################################
"""
This script machine writes all the families and groups (no libraries) so that RMG-database looks cleaner
and does not have duplicate indexes
"""

from rmgpy import settings
from rmgpy.data.rmg import RMGDatabase

database = RMGDatabase()
database.load(settings['database.directory'], kinetics_families='all')

database.save(settings['database.directory'])
コード例 #33
0
                    for group in problems[5]:
                        outputFile.write(group + '\n')
                outputFile.write('\n\n')
if __name__ == '__main__':

    
    #Thermo stuff
#     ThermoDatabase=ThermoDatabase()
#     ThermoDatabase.load(path)
#     ThermoDatabase.save(r'C:\RMG-database\input\thermo_test')
#     ThermoDatabase.save(path)
    FullDatabase=RMGDatabase()
#     path=r'C:\RMG-database\input\thermo'
    path='C:\RMG-database\input'
#     FullDatabase.load(thermoLibraries=)
    FullDatabase.load(path)
    checkFamilies(FullDatabase)
#     trialDir=r'C:\Users\User1\Dropbox\Research\RMG\kinetics\LeaveOneOut\test'
#     trialDir=r'C:\RMG-database\input_test'
#     family=FullDatabase.kinetics.families['Disproportionation']
#     entryKey='Y_1centerbirad;O_Cdrad'
#     
#     test=getKineticsFromRules(family, entryKey)
#     
#     print test.comment
#     print test
    
#     NISTExact(FullDatabase, trialDir)
#     countNodesAll(NISTDatabase, trialDir)
#     consistencyTest(FullDatabase)
#     LeaveOneOut(FullDatabase, trialDir)
コード例 #34
0
ファイル: main.py プロジェクト: jbarlow3/RMG-Py
class RMG:
    """
    A representation of a Reaction Mechanism Generator (RMG) job. The 
    attributes are:
    
    =========================== ================================================
    Attribute                   Description
    =========================== ================================================
    `inputFile`                 The path to the input file
    `logFile`                   The path to the log file
    --------------------------- ------------------------------------------------
    `databaseDirectory`         The directory containing the RMG database
    `thermoLibraries`           The thermodynamics libraries to load
    `reactionLibraries`         The kinetics libraries to load
    `statmechLibraries`         The statistical mechanics libraries to load
    `seedMechanisms`            The seed mechanisms included in the model
    `kineticsFamilies`          The kinetics families to use for reaction generation
    `kineticsDepositories`      The kinetics depositories to use for looking up kinetics in each family
    `kineticsEstimator`         The method to use to estimate kinetics: 'group additivity' or 'rate rules'
    --------------------------- ------------------------------------------------
    `reactionModel`             The core-edge reaction model generated by this job
    `reactionSystems`           A list of the reaction systems used in this job
    `database`                  The RMG database used in this job
    --------------------------- ------------------------------------------------
    `absoluteTolerance`         The absolute tolerance used in the ODE/DAE solver
    `relativeTolerance`         The relative tolerance used in the ODE/DAE solver
    `fluxToleranceKeepInEdge`   The relative species flux below which species are discarded from the edge
    `fluxToleranceMoveToCore`   The relative species flux above which species are moved from the edge to the core
    `fluxToleranceInterrupt`    The relative species flux above which the simulation will halt
    `maximumEdgeSpecies`        The maximum number of edge species allowed at any time
    `termination`               A list of termination targets (i.e :class:`TerminationTime` and :class:`TerminationConversion` objects)
    --------------------------- ------------------------------------------------
    `outputDirectory`           The directory used to save output files
    `scratchDirectory`          The directory used to save temporary files
    `verbosity`                 The level of logging verbosity for console output
    `loadRestart`               ``True`` if restarting a previous job, ``False`` otherwise
    `saveRestartPeriod`         The time period to periodically save a restart file (:class:`Quantity`), or ``None`` for never.
    `units`                     The unit system to use to save output files (currently must be 'si')
    `drawMolecules`             ``True`` to draw pictures of the species in the core, ``False`` otherwise
    `generatePlots`             ``True`` to generate plots of the job execution statistics after each iteration, ``False`` otherwise
    `pressureDependence`        Whether to process unimolecular (pressure-dependent) reaction networks
    `wallTime`                  The maximum amount of CPU time in seconds to expend on this job; used to stop gracefully so we can still get profiling information
    --------------------------- ------------------------------------------------
    `initializationTime`        The time at which the job was initiated, in seconds since the epoch (i.e. from time.time())
    `done`                      Whether the job has completed (there is nothing new to add)
    =========================== ================================================
    
    """
    
    def __init__(self, inputFile=None, logFile=None, outputDirectory=None, scratchDirectory=None):
        self.inputFile = inputFile
        self.logFile = logFile
        self.outputDirectory = outputDirectory
        self.scratchDirectory = scratchDirectory
        self.clear()
    
    def clear(self):
        """
        Clear all loaded information about the job (except the file paths).
        """
        self.databaseDirectory = None
        self.thermoLibraries = None
        self.reactionLibraries = None
        self.statmechLibraries = None
        self.seedMechanisms = None
        self.kineticsFamilies = None
        self.kineticsDepositories = None
        self.kineticsEstimator = 'group additivity'
        
        self.reactionModel = None
        self.reactionSystems = None
        self.database = None
        
        self.fluxToleranceKeepInEdge = 0.0
        self.fluxToleranceMoveToCore = 1.0
        self.fluxToleranceInterrupt = 1.0
        self.absoluteTolerance = 1.0e-8
        self.relativeTolerance = 1.0e-4
        self.maximumEdgeSpecies = 1000000
        self.termination = []
        
        self.done = False
        self.verbosity = logging.INFO
        self.loadRestart = None
        self.saveRestartPeriod = None
        self.units = 'si'
        self.drawMolecules = None
        self.generatePlots = None
        self.saveConcentrationProfiles = None
        self.pressureDependence = None
        self.wallTime = 0
        self.initializationTime = 0
    
    def loadInput(self, path=None):
        """
        Load an RMG job from the input file located at `inputFile`, or
        from the `inputFile` attribute if not given as a parameter.
        """
        from input import readInputFile
        if path is None: path = self.inputFile
        readInputFile(path, self)
        self.reactionModel.kineticsEstimator = self.kineticsEstimator
        if self.pressureDependence:
            # If the output directory is not yet set, then set it to the same
            # directory as the input file by default
            if not self.outputDirectory:
                self.outputDirectory = os.path.dirname(path)
            self.pressureDependence.outputFile = self.outputDirectory
            self.reactionModel.pressureDependence = self.pressureDependence
        
    def checkInput(self):
        """
        Check for a few common mistakes in the input file.
        """
        if self.pressureDependence:
            for index, reactionSystem in enumerate(self.reactionSystems):
                assert (reactionSystem.T.value_si < self.pressureDependence.Tmax.value_si), "Reaction system T is above pressureDependence range."
                assert (reactionSystem.T.value_si > self.pressureDependence.Tmin.value_si), "Reaction system T is below pressureDependence range."
                assert (reactionSystem.P.value_si < self.pressureDependence.Pmax.value_si), "Reaction system P is above pressureDependence range."
                assert (reactionSystem.P.value_si > self.pressureDependence.Pmin.value_si), "Reaction system P is below pressureDependence range."
            assert any([not s.reactive for s in reactionSystem.initialMoleFractions.keys()]), \
                "Pressure Dependence calculations require at least one inert (nonreacting) species for the bath gas."

    def saveInput(self, path=None):
        """
        Save an RMG job to the input file located at `path`, or
        from the `outputFile` attribute if not given as a parameter.
        """
        from input import saveInputFile
        if path is None: path = self.outputFile
        saveInputFile(path, self)
        
    def loadDatabase(self):
        
        self.database = RMGDatabase()
        self.database.load(
            path = self.databaseDirectory,
            thermoLibraries = self.thermoLibraries,
            reactionLibraries = [library for library, option in self.reactionLibraries],
            seedMechanisms = self.seedMechanisms,
            kineticsFamilies = self.kineticsFamilies,
            kineticsDepositories = self.kineticsDepositories,
            #frequenciesLibraries = self.statmechLibraries,
            depository = False, # Don't bother loading the depository information, as we don't use it
        )
        if self.kineticsEstimator == 'rate rules':
            logging.info('Adding rate rules from training set in kinetics families...')
            for family in self.database.kinetics.families.values():
                family.addKineticsRulesFromTrainingSet(thermoDatabase=self.database.thermo)
            logging.info('Filling in rate rules in kinetics families by averaging...')
            for family in self.database.kinetics.families.values():
                family.fillKineticsRulesByAveragingUp()
    
    def initialize(self, args):
        """
        Initialize an RMG job using the command-line arguments `args` as returned
        by the :mod:`argparse` package.
        """
    
        # Save initialization time
        self.initializationTime = time.time()
    
        # Log start timestamp
        logging.info('RMG execution initiated at ' + time.asctime() + '\n')
    
        # Print out RMG header
        self.logHeader()
        
        # Set directories
        self.outputDirectory = args.output_directory
        self.scratchDirectory = args.scratch_directory
        
        # Read input file
        self.loadInput(args.file[0])
        
        # Check input file 
        self.checkInput()
    
        # See if memory profiling package is available
        try:
            import os
            import psutil
        except ImportError:
            logging.info('Optional package dependency "psutil" not found; memory profiling information will not be saved.')
    
        # See if spreadsheet writing package is available
        if self.saveConcentrationProfiles:
            try:
                xlwt
            except NameError:
                logging.warning('Package dependency "xlwt" not loaded; reaction system concentration profiles will not be saved, despite saveConcentrationProfiles = True option.')
                self.saveConcentrationProfiles = False
        
        # Make output subdirectories
        self.makeOutputSubdirectory('plot')
        self.makeOutputSubdirectory('species')
        self.makeOutputSubdirectory('pdep')
        self.makeOutputSubdirectory('chemkin')
        self.makeOutputSubdirectory('solver')
        
        # Load databases
        self.loadDatabase()
    
        # Set wall time
        if args.walltime == '0': 
            self.wallTime = 0
        else:
            data = args.walltime[0].split(':')
            if len(data) == 1:
                self.wallTime = int(data[-1])
            elif len(data) == 2:
                self.wallTime = int(data[-1]) + 60 * int(data[-2])
            elif len(data) == 3:
                self.wallTime = int(data[-1]) + 60 * int(data[-2]) + 3600 * int(data[-3])
            elif len(data) == 4:
                self.wallTime = int(data[-1]) + 60 * int(data[-2]) + 3600 * int(data[-3]) + 86400 * int(data[-4])
            else:
                raise ValueError('Invalid format for wall time; should be HH:MM:SS.')
    
        # Delete previous HTML file
        from rmgpy.rmg.output import saveOutputHTML
        saveOutputHTML(os.path.join(self.outputDirectory, 'output.html'), self.reactionModel)
        
        # Initialize reaction model
        if args.restart:
            self.loadRestartFile(os.path.join(self.outputDirectory,'restart.pkl'))
        else:
    
            # Seed mechanisms: add species and reactions from seed mechanism
            # DON'T generate any more reactions for the seed species at this time
            for seedMechanism in self.seedMechanisms:
                self.reactionModel.addSeedMechanismToCore(seedMechanism, react=False)

            # Reaction libraries: add species and reactions from reaction library to the edge so
            # that RMG can find them if their rates are large enough
            for library, option in self.reactionLibraries:
                self.reactionModel.addReactionLibraryToEdge(library)
            
            # Add nonreactive species (e.g. bath gases) to core first
            # This is necessary so that the PDep algorithm can identify the bath gas
            self.reactionModel.enlarge([spec for spec in self.initialSpecies if not spec.reactive])
            # Then add remaining reactive species
            for spec in self.initialSpecies:
                spec.generateThermoData(self.database)
            self.reactionModel.enlarge([spec for spec in self.initialSpecies if spec.reactive])
            
            # Save a restart file if desired
            if self.saveRestartPeriod:
                self.saveRestartFile(os.path.join(self.outputDirectory,'restart.pkl'), self.reactionModel)
    
    def execute(self, args):
        """
        Execute an RMG job using the command-line arguments `args` as returned
        by the :mod:`argparse` package.
        """
    
        self.initialize(args)
        
        # RMG execution statistics
        coreSpeciesCount = []
        coreReactionCount = []
        edgeSpeciesCount = []
        edgeReactionCount = []
        execTime = []
        restartSize = []
        memoryUse = []

        self.done = False
        self.saveEverything()
        # Main RMG loop
        while not self.done:
    
            if self.saveConcentrationProfiles:
                # self.saveConcentrationProfiles should have been set to false if xlwt cannot be loaded
                workbook = xlwt.Workbook()
                
            self.done = True
            objectsToEnlarge = []
            allTerminated = True
            for index, reactionSystem in enumerate(self.reactionSystems):
    
                if self.saveConcentrationProfiles:
                    worksheet = workbook.add_sheet('#{0:d}'.format(index+1))
                else:
                    worksheet = None
                
                # Conduct simulation
                pdepNetworks = []
                for source, networks in self.reactionModel.networkDict.items():
                    pdepNetworks.extend(networks)
                logging.info('Conducting simulation of reaction system %s...' % (index+1))
                terminated, obj = reactionSystem.simulate(
                    coreSpecies = self.reactionModel.core.species,
                    coreReactions = self.reactionModel.core.reactions,
                    edgeSpecies = self.reactionModel.edge.species,
                    edgeReactions = self.reactionModel.edge.reactions,
                    toleranceKeepInEdge = self.fluxToleranceKeepInEdge,
                    toleranceMoveToCore = self.fluxToleranceMoveToCore,
                    toleranceInterruptSimulation = self.fluxToleranceInterrupt,
                    pdepNetworks = pdepNetworks,
                    worksheet = worksheet,
                    absoluteTolerance = self.absoluteTolerance,
                    relativeTolerance = self.relativeTolerance,
                )
                allTerminated = allTerminated and terminated
                logging.info('')
                
                # If simulation is invalid, note which species should be added to
                # the core
                if obj:
                    if isinstance(obj, PDepNetwork):
                        # Determine which species in that network has the highest leak rate
                        # We do this here because we need a temperature and pressure
                        # Store the maximum leak species along with the associated network
                        obj = (obj, obj.getMaximumLeakSpecies(reactionSystem.T.value_si, reactionSystem.P.value_si))
                    objectsToEnlarge.append(obj)
                    self.done = False
    
            if self.saveConcentrationProfiles:
                workbook.save(os.path.join(self.outputDirectory, 'solver', 'simulation_{0:d}.xls'.format(len(self.reactionModel.core.species))))
    
            if not self.done: # There is something that needs exploring/enlarging
    
                # If we reached our termination conditions, then try to prune
                # species from the edge
                if allTerminated:
                    self.reactionModel.prune(self.reactionSystems, self.fluxToleranceKeepInEdge, self.maximumEdgeSpecies)
    
                # Enlarge objects identified by the simulation for enlarging
                # These should be Species or Network objects
                logging.info('')
                objectsToEnlarge = list(set(objectsToEnlarge))
                self.reactionModel.enlarge(objectsToEnlarge)

            self.saveEverything()

            # Update RMG execution statistics
            logging.info('Updating RMG execution statistics...')
            coreSpec, coreReac, edgeSpec, edgeReac = self.reactionModel.getModelSize()
            coreSpeciesCount.append(coreSpec)
            coreReactionCount.append(coreReac)
            edgeSpeciesCount.append(edgeSpec)
            edgeReactionCount.append(edgeReac)
            execTime.append(time.time() - self.initializationTime)
            elapsed = execTime[-1]
            seconds = elapsed % 60
            minutes = (elapsed - seconds) % 3600 / 60
            hours = (elapsed - seconds - minutes * 60) % (3600 * 24) / 3600
            days = (elapsed - seconds - minutes * 60 - hours * 3600) / (3600 * 24)
            logging.info('    Execution time (DD:HH:MM:SS): '
                '{0:02}:{1:02}:{2:02}:{3:02}'.format(int(days), int(hours), int(minutes), int(seconds)))
            try:
                import psutil
                process = psutil.Process(os.getpid())
                rss, vms = process.get_memory_info()
                memoryUse.append(rss / 1.0e6)
                logging.info('    Memory used: %.2f MB' % (memoryUse[-1]))
            except ImportError:
                memoryUse.append(0.0)
            if os.path.exists(os.path.join(self.outputDirectory,'restart.pkl.gz')):
                restartSize.append(os.path.getsize(os.path.join(self.outputDirectory,'restart.pkl.gz')) / 1.0e6)
                logging.info('    Restart file size: %.2f MB' % (restartSize[-1]))
            else:
                restartSize.append(0.0)
            self.saveExecutionStatistics(execTime, coreSpeciesCount, coreReactionCount, edgeSpeciesCount, edgeReactionCount, memoryUse, restartSize)
            if self.generatePlots:
                self.generateExecutionPlots(execTime, coreSpeciesCount, coreReactionCount, edgeSpeciesCount, edgeReactionCount, memoryUse, restartSize)
    
            logging.info('')
    
            # Consider stopping gracefully if the next iteration might take us
            # past the wall time
            if self.wallTime > 0 and len(execTime) > 1:
                t = execTime[-1]
                dt = execTime[-1] - execTime[-2]
                if t + 3 * dt > self.wallTime:
                    logging.info('MODEL GENERATION TERMINATED')
                    logging.info('')
                    logging.info('There is not enough time to complete the next iteration before the wall time is reached.')
                    logging.info('The output model may be incomplete.')
                    logging.info('')
                    coreSpec, coreReac, edgeSpec, edgeReac = self.reactionModel.getModelSize()
                    logging.info('The current model core has %s species and %s reactions' % (coreSpec, coreReac))
                    logging.info('The current model edge has %s species and %s reactions' % (edgeSpec, edgeReac))
                    return
    
        # Write output file
        logging.info('')
        logging.info('MODEL GENERATION COMPLETED')
        logging.info('')
        coreSpec, coreReac, edgeSpec, edgeReac = self.reactionModel.getModelSize()
        logging.info('The final model core has %s species and %s reactions' % (coreSpec, coreReac))
        logging.info('The final model edge has %s species and %s reactions' % (edgeSpec, edgeReac))
        
        self.finish()
        
    def saveEverything(self):
        """
        Saves the output HTML, the Chemkin file, and the Restart file (if appropriate).
        
        The restart file is only saved if self.saveRestartPeriod or self.done.
        """
        # If the user specifies it, add unused reaction library reactions to
        # an additional output species and reaction list which is written to the ouput HTML
        # file as well as the chemkin file
        self.reactionModel.outputSpeciesList = []
        self.reactionModel.outputReactionList = []
        for library, option in self.reactionLibraries:
            if option:
                self.reactionModel.addReactionLibraryToOutput(library)
                
        # Save the current state of the model core to a pretty HTML file
        self.saveOutputHTML()
        # Save a Chemkin file containing the current model core
        self.saveChemkinFile()
        # Save the restart file if desired
        if self.saveRestartPeriod or self.done:
            self.saveRestartFile( os.path.join(self.outputDirectory,'restart.pkl'),
                                  self.reactionModel,
                                  delay=0 if self.done else self.saveRestartPeriod.value_si
                                )
            
            
    def finish(self):
        """
        Complete the model generation.
        """
        # Log end timestamp
        logging.info('')
        logging.info('RMG execution terminated at ' + time.asctime())
    
    def getGitCommit(self):
        import subprocess
        from rmgpy import getPath
        try:
            return subprocess.check_output(['git', 'log',
                                            '--format=%H%n%cd', '-1'],
                                            cwd=getPath()).splitlines()
        except:
            return '', ''
    
    def logHeader(self, level=logging.INFO):
        """
        Output a header containing identifying information about RMG to the log.
        """
    
        logging.log(level, '#################################################')
        logging.log(level, '# RMG - Reaction Mechanism Generator            #')
        logging.log(level, '# Version: 0.1.0 (14 May 2009)                  #')
        logging.log(level, '# Authors: RMG Developers ([email protected])     #')
        logging.log(level, '# P.I.:    William H. Green ([email protected])   #')
        logging.log(level, '# Website: http://rmg.sourceforge.net/          #')
        logging.log(level, '#################################################\n')
    
        import os
    
        head, date = self.getGitCommit()
        if head != '' and date != '':
            logging.log(level, 'The current git HEAD is:')
            logging.log(level, '\t%s' % head)
            logging.log(level, '\t%s' % date)
    
        logging.log(level, '')
    
    def makeOutputSubdirectory(self, folder):
        """
        Create a subdirectory `folder` in the output directory. If the folder
        already exists (e.g. from a previous job) its contents are deleted.
        """
        dir = os.path.join(self.outputDirectory, folder)
        if os.path.exists(dir):
            # The directory already exists, so delete it (and all its content!)
            shutil.rmtree(dir)
        os.mkdir(dir)
    
    def loadRestartFile(self, path):
        """
        Load a restart file at `path` on disk.
        """
    
        import cPickle
    
        # Unpickle the reaction model from the specified restart file
        logging.info('Loading previous restart file...')
        f = open(path, 'rb')
        self.reactionModel = cPickle.load(f)
        f.close()
    
        # A few things still point to the species in the input file, so update
        # those to point to the equivalent species loaded from the restart file
    
        # The termination conversions still point to the old species
        from rmgpy.solver.base import TerminationConversion
        for reactionSystem in self.reactionSystems:
            for term in reactionSystem.termination:
                if isinstance(term, TerminationConversion):
                    term.species, isNew = self.reactionModel.makeNewSpecies(term.species.molecule[0], term.species.label, term.species.reactive)
    
        # The initial mole fractions in the reaction systems still point to the old species
        for reactionSystem in self.reactionSystems:
            initialMoleFractions = {}
            for spec0, moleFrac in reactionSystem.initialMoleFractions.iteritems():
                spec, isNew = self.reactionModel.makeNewSpecies(spec0.molecule[0], spec0.label, spec0.reactive)
                initialMoleFractions[spec] = moleFrac
            reactionSystem.initialMoleFractions = initialMoleFractions
    
        # The reactions and reactionDict still point to the old reaction families
        reactionDict = {}
        oldFamilies = self.reactionModel.reactionDict.keys()
        for family0 in self.reactionModel.reactionDict:
    
            # Find the equivalent library or family in the newly-loaded kinetics database
            family = None
            if isinstance(family0, KineticsLibrary):
                for label, database in self.database.kinetics.libraries.iteritems():
                    if database.label == family0.label:
                        family = database
                        break
            elif isinstance(family0, KineticsFamily):
                for label, database in self.database.kinetics.families.iteritems():
                    if database.label == family0.label:
                        family = database
                        break    
            else:
                import pdb; pdb.set_trace()
            if family is None:
                raise Exception("Unable to find matching reaction family for %s" % family0.label)
    
            # Update each affected reaction to point to that new family
            # Also use that new family in a duplicate reactionDict
            reactionDict[family] = {}
            for reactant1 in self.reactionModel.reactionDict[family0]:
                reactionDict[family][reactant1] = {}
                for reactant2 in self.reactionModel.reactionDict[family0][reactant1]:
                    reactionDict[family][reactant1][reactant2] = []
                    if isinstance(family0, KineticsLibrary):
                        for rxn in self.reactionModel.reactionDict[family0][reactant1][reactant2]:
                            assert isinstance(rxn, LibraryReaction)
                            rxn.library = family
                            reactionDict[family][reactant1][reactant2].append(rxn)
                    elif isinstance(family0, KineticsFamily):
                        for rxn in self.reactionModel.reactionDict[family0][reactant1][reactant2]:
                            assert isinstance(rxn, TemplateReaction)
                            rxn.family = family
                            reactionDict[family][reactant1][reactant2].append(rxn)
        
        self.reactionModel.reactionDict = reactionDict
    
    def saveOutputHTML(self):
        """
        Save the current reaction model to a pretty HTML file.
        """
        logging.info('Saving current model to HTML file...')
        from rmgpy.rmg.output import saveOutputHTML
        saveOutputHTML(os.path.join(self.outputDirectory, 'output.html'), self.reactionModel)
        
    def saveChemkinFile(self):
        """
        Save the current reaction model to a Chemkin file.
        """        
        logging.info('Saving current model to Chemkin file...')
        this_chemkin_path = os.path.join(self.outputDirectory, 'chemkin', 'chem%04i.inp' % len(self.reactionModel.core.species))
        latest_chemkin_path = os.path.join(self.outputDirectory, 'chemkin','chem.inp')
        latest_dictionary_path = os.path.join(self.outputDirectory, 'chemkin','species_dictionary.txt')
        self.reactionModel.saveChemkinFile(this_chemkin_path, latest_dictionary_path)
        if os.path.exists(latest_chemkin_path):
            os.unlink(latest_chemkin_path)
        shutil.copy2(this_chemkin_path,latest_chemkin_path)
        
    def saveRestartFile(self, path, reactionModel, delay=0):
        """
        Save a restart file to `path` on disk containing the contents of the
        provided `reactionModel`. The `delay` parameter is a time in seconds; if
        the restart file is not at least that old, the save is aborted. (Use the
        default value of 0 to force the restart file to be saved.)
        """
        import cPickle
        
        # Saving of a restart file is very slow (likely due to all the Quantity objects)
        # Therefore, to save it less frequently, don't bother if the restart file is less than an hour old
        if os.path.exists(path) and time.time() - os.path.getmtime(path) < delay:
            logging.info('Not saving restart file in this iteration.')
            return
        
        # Pickle the reaction model to the specified file
        # We also compress the restart file to save space (and lower the disk read/write time)
        logging.info('Saving restart file...')
        f = open(path, 'wb')
        cPickle.dump(reactionModel, f, cPickle.HIGHEST_PROTOCOL)
        f.close()
    
    def saveExecutionStatistics(self, execTime, coreSpeciesCount, coreReactionCount,
        edgeSpeciesCount, edgeReactionCount, memoryUse, restartSize):
        """
        Save the statistics of the RMG job to an Excel spreadsheet for easy viewing
        after the run is complete. The statistics are saved to the file
        `statistics.xls` in the output directory. The ``xlwt`` package is used to
        create the spreadsheet file; if this package is not installed, no file is
        saved.
        """
    
        # Attempt to import the xlwt package; return if not installed
        try:
            xlwt
        except NamerError:
            logging.warning('Package xlwt not loaded. Unable to save execution statistics.')
            return
    
        # Create workbook and sheet for statistics to be places
        workbook = xlwt.Workbook()
        sheet = workbook.add_sheet('Statistics')
    
        # First column is execution time
        sheet.write(0,0,'Execution time (s)')
        for i, etime in enumerate(execTime):
            sheet.write(i+1,0,etime)
    
        # Second column is number of core species
        sheet.write(0,1,'Core species')
        for i, count in enumerate(coreSpeciesCount):
            sheet.write(i+1,1,count)
    
        # Third column is number of core reactions
        sheet.write(0,2,'Core reactions')
        for i, count in enumerate(coreReactionCount):
            sheet.write(i+1,2,count)
    
        # Fourth column is number of edge species
        sheet.write(0,3,'Edge species')
        for i, count in enumerate(edgeSpeciesCount):
            sheet.write(i+1,3,count)
    
        # Fifth column is number of edge reactions
        sheet.write(0,4,'Edge reactions')
        for i, count in enumerate(edgeReactionCount):
            sheet.write(i+1,4,count)
    
        # Sixth column is memory used
        sheet.write(0,5,'Memory used (MB)')
        for i, memory in enumerate(memoryUse):
            sheet.write(i+1,5,memory)
    
        # Seventh column is restart file size
        sheet.write(0,6,'Restart file size (MB)')
        for i, memory in enumerate(restartSize):
            sheet.write(i+1,6,memory)
    
        # Save workbook to file
        fstr = os.path.join(self.outputDirectory, 'statistics.xls')
        workbook.save(fstr)
    
    def generateExecutionPlots(self, execTime, coreSpeciesCount, coreReactionCount,
        edgeSpeciesCount, edgeReactionCount, memoryUse, restartSize):
        """
        Generate a number of plots describing the statistics of the RMG job,
        including the reaction model core and edge size and memory use versus
        execution time. These will be placed in the output directory in the plot/
        folder.
        """
    
        logging.info('Generating plots of execution statistics...')
    
        import matplotlib.pyplot as plt
        fig = plt.figure()
        ax1 = fig.add_subplot(111)
        ax1.semilogx(execTime, coreSpeciesCount, 'o-b')
        ax1.set_xlabel('Execution time (s)')
        ax1.set_ylabel('Number of core species')
        ax2 = ax1.twinx()
        ax2.semilogx(execTime, coreReactionCount, 'o-r')
        ax2.set_ylabel('Number of core reactions')
        plt.savefig(os.path.join(self.outputDirectory, 'plot/coreSize.svg'))
        plt.clf()
    
        fig = plt.figure()
        ax1 = fig.add_subplot(111)
        ax1.loglog(execTime, edgeSpeciesCount, 'o-b')
        ax1.set_xlabel('Execution time (s)')
        ax1.set_ylabel('Number of edge species')
        ax2 = ax1.twinx()
        ax2.loglog(execTime, edgeReactionCount, 'o-r')
        ax2.set_ylabel('Number of edge reactions')
        plt.savefig(os.path.join(self.outputDirectory, 'plot/edgeSize.svg'))
        plt.clf()
    
        fig = plt.figure()
        ax1 = fig.add_subplot(111)
        ax1.semilogx(execTime, memoryUse, 'o-k')
        ax1.semilogx(execTime, restartSize, 'o-g')
        ax1.set_xlabel('Execution time (s)')
        ax1.set_ylabel('Memory (MB)')
        ax1.legend(['RAM', 'Restart file'], loc=2)
        plt.savefig(os.path.join(self.outputDirectory, 'plot/memoryUse.svg'))
        plt.clf()
        
    def loadRMGJavaInput(self, path):
        """
        Load an RMG-Java job from the input file located at `inputFile`, or
        from the `inputFile` attribute if not given as a parameter.
        """
        
        # NOTE: This function is currently incomplete!
        # It only loads a subset of the available information.
    
        self.reactionModel = CoreEdgeReactionModel()
        self.initialSpecies = []
        self.reactionSystems = []
    
        Tlist = []; Plist = []; concentrationList = []; speciesDict = {}
        termination = []; atol=1e-16; rtol=1e-8
        
        with open(path, 'r') as f:
            line = self.readMeaningfulLineJava(f)
            while line != '':
                
                
                if line.startswith('TemperatureModel:'):
                    tokens = line.split()
                    units = tokens[2][1:-1]
                    assert units in ['C', 'F', 'K']
                    if units == 'C':
                        Tlist = [float(T)+273.15 for T in tokens[3:]]
                    elif units == 'F':
                        Tlist = [(float(T)+459.67)*5./9. for T in tokens[3:]]
                    else:
                        Tlist = [float(T) for T in tokens[3:]]
                
                elif line.startswith('PressureModel:'):
                    tokens = line.split()
                    units = tokens[2][1:-1]
                    assert units in ['atm', 'bar', 'Pa', 'torr']
                    if units == 'atm':
                        Plist = [float(P)*101325. for P in tokens[3:]]
                    elif units == 'bar':
                        Plist = [float(P)*100000. for P in tokens[3:]]
                    elif units == 'torr':
                        Plist = [float(P)/760.*101325. for P in tokens[3:]]
                    else:
                        Plist = [float(P) for P in tokens[3:]]
                        
                elif line.startswith('InitialStatus:'):
                    label = ''; concentrations = []; adjlist = ''
                    
                    line = self.readMeaningfulLineJava(f)
                    while line != 'END':
                        
                        if line == '' and label != '':
                            species = Species(label=label, molecule=[Molecule().fromAdjacencyList(adjlist)])
                            self.initialSpecies.append(species)
                            speciesDict[label] = species
                            concentrationList.append(concentrations)
                            label = ''; concentrations = []; adjlist = ''
                        
                        elif line != '' and label == '':
                            tokens = line.split()
                            label = tokens[0]
                            units = tokens[1][1:-1]
                            if tokens[-1] in ['Unreactive', 'ConstantConcentration']:
                                tokens.pop(-1)
                            assert units in ['mol/cm3', 'mol/m3', 'mol/l']
                            if units == 'mol/cm3':
                                concentrations = [float(C)*1.0e6 for C in tokens[2:]]
                            elif units == 'mol/l':
                                concentrations = [float(C)*1.0e3 for C in tokens[2:]]
                            else:
                                concentrations = [float(C) for C in tokens[2:]]
                        
                        elif line != '':
                            adjlist += line + '\n'
                        
                        line = f.readline().strip()
                        if '//' in line: line = line[0:line.index('//')]
                        
                elif line.startswith('InertGas:'):
                    
                    line = self.readMeaningfulLineJava(f)
                    while line != 'END':
                        
                        tokens = line.split()
                        label = tokens[0]
                        assert label in ['N2', 'Ar', 'He', 'Ne']
                        if label == 'Ne':
                            smiles = '[Ne]'
                        elif label == 'Ar':
                            smiles = '[Ar]'
                        elif label == 'He':
                            smiles = '[He]'
                        else:
                            smiles = 'N#N'
                        units = tokens[1][1:-1]
                        assert units in ['mol/cm3', 'mol/m3', 'mol/l']
                        if units == 'mol/cm3':
                            concentrations = [float(C)*1.0e6 for C in tokens[2:]]
                        elif units == 'mol/l':
                            concentrations = [float(C)*1.0e3 for C in tokens[2:]]
                        else:
                            concentrations = [float(C) for C in tokens[2:]]
                        
                        species = Species(label=label, reactive=False, molecule=[Molecule().fromSMILES(smiles)])
                        self.initialSpecies.append(species)
                        speciesDict[label] = species
                        concentrationList.append(concentrations)
                            
                        line = self.readMeaningfulLineJava(f)
                
                elif line.startswith('FinishController:'):
                    
                    # First meaningful line is a termination time or conversion
                    line = self.readMeaningfulLineJava(f)
                    tokens = line.split()
                    if tokens[2].lower() == 'conversion:':
                        label = tokens[3]
                        conversion = float(tokens[4])
                        termination.append(TerminationConversion(spec=speciesDict[label], conv=conversion))
                    elif tokens[2].lower() == 'reactiontime:':
                        time = float(tokens[3])
                        units = tokens[4][1:-1]
                        assert units in ['sec', 'min', 'hr', 'day']
                        if units == 'min':
                            time *= 60.
                        elif units == 'hr':
                            time *= 60. * 60.
                        elif units == 'day':
                            time *= 60. * 60. * 24.
                        termination.append(TerminationTime(time=time))
                            
                    # Second meaningful line is the error tolerance
                    # We're not doing anything with this information yet!
                    line = self.readMeaningfulLineJava(f)
                 
                elif line.startswith('Atol:'):
                    tokens = line.split()
                    atol = float(tokens[1])
                    
                elif line.startswith('Rtol:'):
                    tokens = line.split()
                    rtol = float(tokens[1])
                
                line = self.readMeaningfulLineJava(f)
        
        assert len(Tlist) > 0
        assert len(Plist) > 0
        concentrationList = numpy.array(concentrationList)
        assert concentrationList.shape[1] == 1 or concentrationList.shape[1] == len(Tlist) * len(Plist) 
        
        # Make a reaction system for each (T,P) combination
        systemCounter = 0
        for T in Tlist:
            for P in Plist:
                if concentrationList.shape[1] == 1:
                    concentrations = concentrationList[:,0]
                else:
                    concentrations = concentrationList[:,systemCounter]
                totalConc = numpy.sum(concentrations)
                initialMoleFractions = dict([(self.initialSpecies[i], concentrations[i] / totalConc) for i in range(len(self.initialSpecies))])
                reactionSystem = SimpleReactor(T, P, initialMoleFractions=initialMoleFractions, termination=termination)
                self.reactionSystems.append(reactionSystem)
                systemCounter += 1
    
    def readMeaningfulLineJava(self, f):
        """
        Read a meaningful line from an RMG-Java condition file object `f`,
        returning the line with any comments removed.
        """
        line = f.readline()
        if line != '':
            line = line.strip()
            if '//' in line: line = line[0:line.index('//')]
            while line == '':
                line = f.readline()
                if line == '': break
                line = line.strip()
                if '//' in line: line = line[0:line.index('//')]
        return line
コード例 #35
0
    
################################################################################

if __name__ == '__main__':
    
    #figure out the username
    user = getUsername()    
    # Comment out the line above and uncomment the one below, filling in user information manually if 
    # it cannot be obtained from git or you do not want to extract user info from git.
    # user = "******"        
        

    # Set the import and export paths
    oldPath = 'output/RMG_database'
    newPath = 'input'
    
    print 'Loading old RMG-Java database...'
    database = RMGDatabase()
    database.loadOld(oldPath)
    
    print 'Loading the current database to look for changes...'
    current_database = RMGDatabase()
    current_database.load(newPath)
    
    print 'Setting history of all entries in database...'
    setHistory(database, current_database, user=user)
      
    print 'Saving the new RMG-Py database...'
    database.save(newPath)
    print "Done!"
コード例 #36
0
    def test_restart_thermo(self):
        """
        Test restarting ARC through the ARC class in main.py via the input_dict argument of the API
        Rather than through ARC.py. Check that all files are in place and the log file content.
        """
        restart_path = os.path.join(ARC_PATH, 'arc', 'testing', 'restart',
                                    '1_restart_thermo', 'restart.yml')
        input_dict = read_yaml_file(path=restart_path)
        project = 'arc_project_for_testing_delete_after_usage_restart_thermo'
        project_directory = os.path.join(ARC_PATH, 'Projects', project)
        input_dict['project'], input_dict[
            'project_directory'] = project, project_directory
        arc1 = ARC(**input_dict)
        arc1.execute()
        self.assertEqual(arc1.freq_scale_factor, 0.988)

        self.assertTrue(
            os.path.isfile(
                os.path.join(project_directory, 'output', 'thermo.info')))
        with open(os.path.join(project_directory, 'output', 'thermo.info'),
                  'r') as f:
            thermo_dft_ccsdtf12_bac = False
            for line in f.readlines():
                if 'thermo_DFT_CCSDTF12_BAC' in line:
                    thermo_dft_ccsdtf12_bac = True
                    break
        self.assertTrue(thermo_dft_ccsdtf12_bac)

        with open(
                os.path.join(
                    project_directory,
                    'arc_project_for_testing_delete_after_usage_restart_thermo.info'
                ), 'r') as f:
            sts, n2h3, oet, lot, ap = False, False, False, False, False
            for line in f.readlines():
                if 'Considered the following species and TSs:' in line:
                    sts = True
                elif 'Species N2H3' in line:
                    n2h3 = True
                elif 'Overall time since project initiation:' in line:
                    oet = True
                elif 'Levels of theory used:' in line:
                    lot = True
                elif 'ARC project arc_project_for_testing_delete_after_usage_restart_thermo' in line:
                    ap = True
        self.assertTrue(sts)
        self.assertTrue(n2h3)
        self.assertTrue(oet)
        self.assertTrue(lot)
        self.assertTrue(ap)

        with open(os.path.join(project_directory, 'arc.log'), 'r') as f:
            aei, ver, git, spc, rtm, ldb, therm, src, ter =\
                False, False, False, False, False, False, False, False, False
            for line in f.readlines():
                if 'ARC execution initiated on' in line:
                    aei = True
                elif '#   Version:' in line:
                    ver = True
                elif 'The current git HEAD for ARC is:' in line:
                    git = True
                elif 'Considering species: CH3CO2_rad' in line:
                    spc = True
                elif 'All jobs for species N2H3 successfully converged. Run time' in line:
                    rtm = True
                elif 'Loading the RMG database...' in line:
                    ldb = True
                elif 'Thermodynamics for H2O2' in line:
                    therm = True
                elif 'Sources of thermoproperties determined by RMG for the parity plots:' in line:
                    src = True
                elif 'ARC execution terminated on' in line:
                    ter = True
        self.assertTrue(aei)
        self.assertTrue(ver)
        self.assertTrue(git)
        self.assertTrue(spc)
        self.assertTrue(rtm)
        self.assertTrue(ldb)
        self.assertTrue(therm)
        self.assertTrue(src)
        self.assertTrue(ter)

        self.assertTrue(
            os.path.isfile(
                os.path.join(project_directory, 'output',
                             'thermo_parity_plots.pdf')))

        status = read_yaml_file(
            os.path.join(project_directory, 'output', 'status.yml'))
        self.assertEqual(
            status['CH3CO2_rad']['isomorphism'],
            'opt passed isomorphism check; '
            'Conformers optimized and compared at b3lyp/6-31g(d,p) empiricaldispersion=gd3bj; '
        )
        self.assertTrue(status['CH3CO2_rad']['job_types']['sp'])

        with open(
                os.path.join(project_directory, 'output', 'Species', 'H2O2',
                             'arkane', 'species_dictionary.txt'), 'r') as f:
            lines = f.readlines()
        adj_list = ''
        for line in lines:
            if 'H2O2' not in line:
                adj_list += line
            if line == '\n':
                break
        mol1 = Molecule().from_adjacency_list(adj_list)
        self.assertEqual(mol1.to_smiles(), 'OO')

        thermo_library_path = os.path.join(
            project_directory, 'output', 'RMG libraries', 'thermo',
            'arc_project_for_testing_delete_after_usage_restart_thermo.py')
        new_thermo_library_path = os.path.join(
            rmg_settings['database.directory'], 'thermo', 'libraries',
            'arc_project_for_testing_delete_after_usage_restart_thermo.py')
        # copy the generated library to RMG-database
        shutil.copyfile(thermo_library_path, new_thermo_library_path)
        db = RMGDatabase()
        db.load(
            path=rmg_settings['database.directory'],
            thermo_libraries=[
                'arc_project_for_testing_delete_after_usage_restart_thermo'
            ],
            transport_libraries=[],
            reaction_libraries=[],
            seed_mechanisms=[],
            kinetics_families='none',
            kinetics_depositories=[],
            statmech_libraries=None,
            depository=False,
            solvation=False,
            testing=True,
        )

        spc2 = Species(smiles='CC([O])=O')
        spc2.generate_resonance_structures()
        spc2.thermo = db.thermo.get_thermo_data(spc2)
        self.assertAlmostEqual(spc2.get_enthalpy(298), -212439.26998495663, 1)
        self.assertAlmostEqual(spc2.get_entropy(298), 283.3972662956835, 1)
        self.assertAlmostEqual(spc2.get_heat_capacity(1000), 118.751379824224,
                               1)
        self.assertTrue(
            'arc_project_for_testing_delete_after_usage_restart_thermo' in
            spc2.thermo.comment)

        # delete the generated library from RMG-database
        os.remove(new_thermo_library_path)
コード例 #37
0
                outputFile.write("\n\n")


if __name__ == "__main__":

    databaseProjectRootPath = os.path.dirname(os.path.abspath(__file__))
    # Thermo stuff
    #     ThermoDatabase=ThermoDatabase()
    #     ThermoDatabase.load(path)
    #     ThermoDatabase.save(r'C:\RMG-database\input\thermo_test')
    #     ThermoDatabase.save(path)
    FullDatabase = RMGDatabase()
    #     path=r'C:\RMG-database\input\thermo'
    path = os.path.join(databaseProjectRootPath, "input")
    #     FullDatabase.load(thermoLibraries=)
    FullDatabase.load(path, kineticsFamilies="all")
    checkFamilies(FullDatabase)
#     trialDir=r'C:\Users\User1\Dropbox\Research\RMG\kinetics\LeaveOneOut\test'
#     trialDir=r'C:\RMG-database\input_test'
#     family=FullDatabase.kinetics.families['Disproportionation']
#     entryKey='Y_1centerbirad;O_Cdrad'
#
#     test=getKineticsFromRules(family, entryKey)
#
#     print test.comment
#     print test

#     NISTExact(FullDatabase, trialDir)
#     countNodesAll(NISTDatabase, trialDir)
#     consistencyTest(FullDatabase)
#     LeaveOneOut(FullDatabase, trialDir)
コード例 #38
0
ファイル: input.py プロジェクト: pierrelb/tsScripts
for rxnFamily in rxnFamiles:
	for k, line in enumerate(mechLines):
		if line.startswith('! {0} estimate:'.format(rxnFamily)) or line.startswith('! {0} exact:'.format(rxnFamily)):
			reaction = mechLines[k+1].split()[0]
			if reaction not in gotit:
				gotit.append(reaction)
				rxnList.append((rxnFamily, mechLines[k+1]))
		elif '{0} estimate:'.format(rxnFamily) in line or '{0} exact:'.format(rxnFamily) in line:
			reaction = mechLines[k+1].split()[0]
			if reaction not in gotit:
				gotit.append(reaction)
				rxnList.append((rxnFamily, mechLines[k+1]))

print 'Loading RMG Database ...'
rmgDatabase = RMGDatabase()
rmgDatabase.load(os.path.abspath(os.path.join(os.getenv('RMGpy'), '..', 'RMG-database', 'input')), kineticsFamilies='default')
print 'Finished loading RMG Database ...'

reactionTuple = rxnList[i-1]
rxnFamily, reactionLine = reactionTuple
rxnFormula, A, n, Ea = reactionLine.split()
reactants, products = rxnFormula.split('=')
if rxnFamily in ['H_Abstraction', 'Disproportionation']:
	reactant1, reactant2 = [moleculeDict[j] for j in reactants.split('+')]
	product1, product2 = [moleculeDict[j] for j in products.split('+')]
	rSpecies1 = Species(molecule=[reactant1])
	rSpecies2 = Species(molecule=[reactant2])
	pSpecies1 = Species(molecule=[product1])
	pSpecies2 = Species(molecule=[product2])
	rSpecies1.generateResonanceIsomers()
	rSpecies2.generateResonanceIsomers()
コード例 #39
0
                        help='the csv where we give the ouput')

    args = parser.parse_args()

    path = settings['database.directory']
    database = RMGDatabase()
    databaseType = getDatabaseType(args.file)

    if databaseType == 'kineticsLibrary':

        database.load(
            path,
            thermoLibraries=None,
            transportLibraries=None,
            reactionLibraries=[args.file],
            seedMechanisms=None,
            kineticsFamilies='none',
            kineticsDepositories=[],
            statmechLibraries=None,
            depository=True,
            solvation=True,
        )
        with open(args.output, 'wb') as csvfile:
            csvwriter = csv.writer(csvfile)
            entries = database.kinetics.libraries.values()[0].entries

            headingWritten = False
            for index in entries:
                x = entries[index].data
                if type(x) is Arrhenius:
                    if not headingWritten:
                        headingWritten = True
コード例 #40
0
    i = 1
logging.info("RUNNING WITH JOB NUMBER i = {}".format(i))

rxnFamilies = ['H_Abstraction']  # Only looking at H_abstraction via OOH

logging.info('Loading RMG Database ...')
rmgDatabase = RMGDatabase()
databasePath = os.path.abspath(
    os.path.join(os.getenv('RMGpy', '..'), '..', 'RMG-database', 'input'))
logging.info(databasePath)
rmgDatabase.load(
    databasePath,
    kineticsFamilies=rxnFamilies,
    transportLibraries=[],
    reactionLibraries=[],
    seedMechanisms=[],
    thermoLibraries=[
        'primaryThermoLibrary', 'KlippensteinH2O2', 'thermo_DFT_CCSDTF12_BAC',
        'CBS_QB3_1dHR'
    ],
    solvation=False,
)
logging.info('RMG Database Loaded')

loadSpecies = rmgDatabase.kinetics.families[rxnFamilies[0]]
species_dict_file = os.path.expanduser(
    '~/Code/OOHabstraction/bioTST/generate_reactions_output/chemkin/species_dictionary.txt'
)
species_dict = loadSpecies.getSpecies(species_dict_file)
logging.info("Species Dictionary loaded")
print species_dict
コード例 #41
0
    return


if __name__ == '__main__':
    from rmgpy import settings
    
    # Create the data evaluation directory
    trialDir = os.path.join(settings['database.directory'],'..','testing','eval')
    if not os.path.exists(trialDir):
        os.makedirs(trialDir)
        
    print 'Loading the RMG database...'
    FullDatabase=RMGDatabase()
    FullDatabase.load(settings['database.directory'], 
                      kineticsFamilies='all', 
                      kineticsDepositories='all',
                      thermoLibraries=['primaryThermoLibrary'],   # Use just the primary thermo library, which contains necessary small molecular thermo
                      reactionLibraries=[],
                      )

    # Prepare the database by loading training reactions but not averaging the rate rules
    for family in FullDatabase.kinetics.families.values():
        family.addKineticsRulesFromTrainingSet(thermoDatabase=FullDatabase.thermo)
    
    print '--------------------------------------------'
    print 'Obtaining statistics for the families...'
    obtainKineticsFamilyStatistics(FullDatabase, trialDir)
    
    print '--------------------------------------------'
    print 'Performing the leave on out test on the kinetics families...'
    leaveOneOut(FullDatabase, trialDir, averaging=False)
    
コード例 #42
0
ファイル: databaseTester.py プロジェクト: jabrownmit/RMG-Py

def checkFamilies(FullDatabase):
    databaseLog = logging.getLogger('databaseLog')
    familyStatus = {}
    for family in FullDatabase.kinetics.families:
        databaseLog.error('\nChecking ' + family + "...")
        print 'Checking ' + family + "..."
        familyStatus[family] = FullDatabase.kinetics.families[
            family].checkWellFormed()


if __name__ == '__main__':
    # Set up paths for database and logger
    databaseDirectory = settings['database.directory']  # RMG-database/input
    logPath = os.path.join(databaseDirectory, '..', 'database.log')
    #clear logger if it exists
    if os.path.exists(logPath):
        with open(logPath, 'w'):
            pass
    databaseLog = logging.getLogger('databaseLog')
    fh = logging.FileHandler(logPath)
    fh.setLevel(logging.DEBUG)
    databaseLog.addHandler(fh)
    databaseLog.propagate = False  #prevents these logging messages to being sent to ancestors (so that it doesn't print on console)
    #     logging.basicConfig(filename=logpath, level=logging.ERROR)

    FullDatabase = RMGDatabase()
    FullDatabase.load(databaseDirectory, kineticsFamilies='all')
    checkFamilies(FullDatabase)
コード例 #43
0
from rmgpy.data.rmg import RMGDatabase
from rmgpy.chemkin import saveChemkinFile, saveSpeciesDictionary
from rmgpy.rmg.model import Species
    
################################################################################

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('library', metavar='LIBRARYNAME', type=str, nargs=1,
        help='the name of the kinetic library to be exported')    
    args = parser.parse_args()
    libraryName = args.library[0]

    print 'Loading RMG-Py database...'
    database = RMGDatabase()
    database.load('input/', kineticsFamilies='all', kineticsDepositories='all')
    

    print 'Loading {0} library'.format(libraryName)
    kineticLibrary = database.kinetics.libraries[libraryName]
    
    reactionList = []    
    for index, entry in kineticLibrary.entries.iteritems():
        reaction = entry.item
        reaction.kinetics = entry.data
        reactionList.append(reaction)

    speciesList = []
    index = 0
    for spec in kineticLibrary.getSpecies().values():
        index = index + 1
from rmgpy.rmg.model import Species
from rmgpy import settings

################################################################################

if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument(
        "library", metavar="LIBRARYNAME", type=str, nargs=1, help="the name of the kinetic library to be exported"
    )
    args = parser.parse_args()
    libraryName = args.library[0]

    print "Loading RMG-Py database..."
    database = RMGDatabase()
    database.load(settings["database.directory"], kineticsFamilies="all", kineticsDepositories="all")

    print "Loading {0} library".format(libraryName)
    kineticLibrary = database.kinetics.libraries[libraryName]

    reactionList = []
    for index, entry in kineticLibrary.entries.iteritems():
        reaction = entry.item
        reaction.kinetics = entry.data
        library_reaction = LibraryReaction(
            index=reaction.index,
            reactants=reaction.reactants,
            products=reaction.products,
            reversible=reaction.reversible,
            kinetics=reaction.kinetics,
            library=libraryName,
コード例 #45
0
reaction_list = []
family_list = ['H_Abstraction', 'intra_H_migration']

with open('/home/slakman.b/Code/mech_C8_EF_paper/V3/chem.inp',
          'r') as mech_file:
    for line in mech_file:
        if line.strip().startswith('REACTIONS'): break
    for line in mech_file:
        if line.strip().startswith('!'): break
        if 'H_Abstraction' in line or 'intra_H_migration' in line:
            reaction_list.append(line.strip())

rmg_database = RMGDatabase()
rmg_database.load(settings['database.directory'],
                  kineticsFamilies=family_list,
                  reactionLibraries=[])
kinetics_database = rmg_database.kinetics
families = [kinetics_database.families[f] for f in family_list]

barrier_database = SolvationKinetics()
barrier_database.family = families[0]
barrier_database.load(
    os.path.join(settings['database.directory'], 'kinetics', 'families',
                 "H_Abstraction"), None, None)

barrier_database2 = SolvationKinetics()
barrier_database2.family = families[1]
barrier_database2.load(
    os.path.join(settings['database.directory'], 'kinetics', 'families',
                 "intra_H_migration"), None, None)
コード例 #46
0
ファイル: databaseTester.py プロジェクト: KEHANG/RMG-Py
from rmgpy import settings
from rmgpy.data.rmg import RMGDatabase

def checkFamilies(FullDatabase):
    databaseLog=logging.getLogger('databaseLog')
    familyStatus={}
    for family in FullDatabase.kinetics.families:
        databaseLog.error('\nChecking ' + family + "...")
        print 'Checking ' + family + "..."
        familyStatus[family]=FullDatabase.kinetics.families[family].checkWellFormed()
    
if __name__ == '__main__':
    # Set up paths for database and logger
    databaseDirectory = settings['database.directory']    # RMG-database/input    
    logPath = os.path.join(databaseDirectory, '..', 'database.log')
    #clear logger if it exists
    if os.path.exists(logPath):
        with open(logPath, 'w'): 
            pass
    databaseLog=logging.getLogger('databaseLog')
    fh=logging.FileHandler(logPath)
    fh.setLevel(logging.DEBUG)
    databaseLog.addHandler(fh)
    databaseLog.propagate=False #prevents these logging messages to being sent to ancestors (so that it doesn't print on console)
#     logging.basicConfig(filename=logpath, level=logging.ERROR)

    FullDatabase=RMGDatabase()
    FullDatabase.load(databaseDirectory, kineticsFamilies='all')
    checkFamilies(FullDatabase)

コード例 #47
0
    def test_restart(self):
        """
        Test restarting ARC through the ARC class in main.py via the input_dict argument of the API
        Rather than through ARC.py. Check that all files are in place and tst file content.
        """
        restart_path = os.path.join(arc_path, 'arc', 'testing', 'restart(H,H2O2,N2H3,CH3CO2).yml')
        project = 'arc_project_for_testing_delete_after_usage2'
        project_directory = os.path.join(arc_path, 'Projects', project)
        arc1 = ARC(project=project, ess_settings=dict(),
                   input_dict=restart_path, project_directory=project_directory)
        arc1.execute()

        with open(os.path.join(project_directory, 'output', 'thermo.info'), 'r') as f:
            thermo_sft_ccsdtf12_bac = False
            for line in f.readlines():
                if 'thermo_DFT_CCSDTF12_BAC' in line:
                    thermo_sft_ccsdtf12_bac = True
                    break
        self.assertTrue(thermo_sft_ccsdtf12_bac)

        with open(os.path.join(project_directory, 'arc_project_for_testing_delete_after_usage2.info'), 'r') as f:
            sts, n2h3, oet, lot, ap = False, False, False, False, False
            for line in f.readlines():
                if 'Considered the following species and TSs:' in line:
                    sts = True
                elif 'Species N2H3' in line:
                    n2h3 = True
                elif 'Overall time since project initiation:' in line:
                    oet = True
                elif 'Levels of theory used:' in line:
                    lot = True
                elif 'ARC project arc_project_for_testing_delete_after_usage2' in line:
                    ap = True
        self.assertTrue(sts)
        self.assertTrue(n2h3)
        self.assertTrue(oet)
        self.assertTrue(lot)
        self.assertTrue(ap)

        with open(os.path.join(project_directory, 'arc.log'), 'r') as f:
            aei, ver, git, spc, rtm, ldb, therm, src, ter = False, False, False, False, False, False, False, False, False
            for line in f.readlines():
                if 'ARC execution initiated on' in line:
                    aei = True
                elif '#   Version:' in line:
                    ver = True
                elif 'The current git HEAD for ARC is:' in line:
                    git = True
                elif 'Considering species: CH3CO2_rad' in line:
                    spc = True
                elif 'All jobs for species N2H3 successfully converged. Run time: 1:16:03' in line:
                    rtm = True
                elif 'Loading the RMG database...' in line:
                    ldb = True
                elif 'Thermodynamics for H2O2:' in line:
                    therm = True
                elif 'Sources of thermoproperties determined by RMG for the parity plots:' in line:
                    src = True
                elif 'ARC execution terminated on' in line:
                    ter = True
        self.assertTrue(aei)
        self.assertTrue(ver)
        self.assertTrue(git)
        self.assertTrue(spc)
        self.assertTrue(rtm)
        self.assertTrue(ldb)
        self.assertTrue(therm)
        self.assertTrue(src)
        self.assertTrue(ter)

        self.assertTrue(os.path.isfile(os.path.join(project_directory, 'output', 'thermo_parity_plots.pdf')))

        with open(os.path.join(project_directory, 'output', 'Species', 'H2O2', 'species_dictionary.txt'), 'r') as f:
            lines = f.readlines()
        adj_list = str(''.join([line for line in lines if (line and 'H2O2' not in line)]))
        mol1 = Molecule().fromAdjacencyList(adj_list)
        self.assertEqual(mol1.toSMILES(), str('OO'))

        thermo_library_path = os.path.join(project_directory, 'output', 'RMG libraries', 'thermo',
                                           'arc_project_for_testing_delete_after_usage2.py')
        new_thermo_library_path = os.path.join(settings['database.directory'], 'thermo', 'libraries',
                                               'arc_project_for_testing_delete_after_usage2.py')
        # copy the generated library to RMG-database
        shutil.copyfile(thermo_library_path, new_thermo_library_path)
        db = RMGDatabase()
        db.load(
            path=settings['database.directory'],
            thermoLibraries=[str('arc_project_for_testing_delete_after_usage2')],
            transportLibraries=[],
            reactionLibraries=[],
            seedMechanisms=[],
            kineticsFamilies='none',
            kineticsDepositories=[],
            statmechLibraries=None,
            depository=False,
            solvation=False,
            testing=True,
        )

        spc2 = Species().fromSMILES(str('CC([O])=O'))
        spc2.generate_resonance_structures()
        spc2.thermo = db.thermo.getThermoData(spc2)
        self.assertAlmostEqual(spc2.getEnthalpy(298), -178003.44650359568, 1)
        self.assertAlmostEqual(spc2.getEntropy(298), 283.5983103176096, 1)
        self.assertAlmostEqual(spc2.getHeatCapacity(1000), 118.99753808225603, 1)
        self.assertTrue('arc_project_for_testing_delete_after_usage2' in spc2.thermo.comment)

        # delete the generated library from RMG-database
        os.remove(new_thermo_library_path)
コード例 #48
0
    connection_id = fig.canvas.mpl_connect('pick_event', onpick)

    pylab.show()

################################################################################

if __name__ == '__main__':

    import argparse
    
    parser = argparse.ArgumentParser()
    parser.add_argument('depository', metavar='<depository>', type=str, nargs=1, help='the depository to use')
    
    args = parser.parse_args()
    
    print 'Loading RMG database...'
    from rmgpy.data.rmg import RMGDatabase
    database = RMGDatabase()
    database.load('input')

    try:
        depositories = [database.kinetics.depository[label] for label in args.depository]
    except KeyError:
        print e
        print 'The specified depository "{0}" was invalid.'.format(label)
        quit()
        
    print 'Generating Evans-Polanyi data...'
    for depository in depositories:
        generateEvansPolanyiPlot(depository, database)