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)
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)
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
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()
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!"
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!"
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)
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)
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))
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)
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)
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
def loadDatabase(): print 'Loading RMG database...' from rmgpy.data.rmg import RMGDatabase database = RMGDatabase() database.load('input') return database
""" 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!"
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()
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)
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)
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
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?
# 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'])
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)
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()
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)
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)
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
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 '--------------------------------------------'
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
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)
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)
# 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'])
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)
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
################################################################################ 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!"
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)
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)
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()
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
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
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)
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)
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,
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)
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)
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)
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)