def generateReactions(database, reactants, products=None, only_families=None, resonance=True):
    """
    Generate the reactions (and associated kinetics) for a given set of
    `reactants` and an optional set of `products`. A list of reactions is
    returned, with a reaction for each matching kinetics entry in any part of
    the database. This means that the same reaction may appear multiple times
    with different kinetics in the output.

    If `only_families` is a list of strings, only those labeled families are 
    used: no libraries and no RMG-Java kinetics are returned.
    """
    from rmgpy.rmg.model import getFamilyLibraryObject
    # get RMG-py reactions
    reaction_list = database.kinetics.generate_reactions(reactants, products, only_families=only_families, resonance=resonance)
    if len(reactants) == 1:
        # if only one reactant, react it with itself bimolecularly, with RMG-py
        # the java version already does this (it includes A+A reactions when you react A)
        reactants2 = [reactants[0], reactants[0]]
        reaction_list.extend(database.kinetics.generate_reactions(reactants2, products, only_families=only_families, resonance=resonance))
    
    # get RMG-py kinetics
    reaction_data_list = []
    template_reactions = []
    for reaction in reaction_list:
        # If the reaction already has kinetics (e.g. from a library),
        # assume the kinetics are satisfactory
        if reaction.kinetics is not None:
            reaction_data_list.append(reaction)
        else:
            # Set the reaction kinetics
            # Only reactions from families should be missing kinetics
            assert isinstance(reaction, TemplateReaction)

            # Determine if we've already processed an isomorphic reaction with a different template
            duplicate = False
            for t_rxn in template_reactions:
                if reaction.isIsomorphic(t_rxn):
                    assert set(reaction.template) != set(t_rxn.template), 'There should not be duplicate reactions with identical templates.'
                    duplicate = True
                    break
            else:
                # We haven't encountered this reaction yet, so add it to the list
                template_reactions.append(reaction)

            # Get all of the kinetics for the reaction
            family = getFamilyLibraryObject(reaction.family)
            kineticsList = family.getKinetics(reaction, templateLabels=reaction.template, degeneracy=reaction.degeneracy, returnAllKinetics=True)
            if family.ownReverse and hasattr(reaction,'reverse'):
                kineticsListReverse = family.getKinetics(reaction.reverse, templateLabels=reaction.reverse.template, degeneracy=reaction.reverse.degeneracy, returnAllKinetics=True)
                for kinetics, source, entry, isForward in kineticsListReverse:
                    for kinetics0, source0, entry0, isForward0 in kineticsList:
                        if source0 is not None and source is not None and entry0 is entry and isForward != isForward0:
                            # We already have this estimate from the forward direction, so don't duplicate it in the results
                            break
                    else:
                        kineticsList.append([kinetics, source, entry, not isForward])
                # We're done with the "reverse" attribute, so delete it to save a bit of memory
                delattr(reaction,'reverse')
            # Make a new reaction object for each kinetics result
            for kinetics, source, entry, isForward in kineticsList:
                if duplicate and source != 'rate rules':
                    # We've already processed this reaction with a different template,
                    # so we only need the new rate rule estimates
                    continue

                if isForward:
                    reactant_species = reaction.reactants[:]
                    product_species = reaction.products[:]
                else:
                    reactant_species = reaction.products[:]
                    product_species = reaction.reactants[:]
                
                if source == 'rate rules' or source == 'group additivity':
                    rxn = TemplateReaction(
                        reactants = reactant_species,
                        products = product_species,
                        kinetics = kinetics,
                        degeneracy = reaction.degeneracy,
                        reversible = reaction.reversible,
                        family = reaction.family,
                        estimator = source,
                        template = reaction.template,
                    )
                else:
                    rxn = DepositoryReaction(
                        reactants = reactant_species,
                        products = product_species,
                        kinetics = kinetics,
                        degeneracy = reaction.degeneracy,
                        reversible = reaction.reversible,
                        depository = source,
                        family = reaction.family,
                        entry = entry,
                    )                    
                    
                reaction_data_list.append(rxn)

    return reaction_data_list
Exemplo n.º 2
0
def generateReactions(database, reactants, products=None, only_families=None):
    """
    Generate the reactions (and associated kinetics) for a given set of
    `reactants` and an optional set of `products`. A list of reactions is
    returned, with a reaction for each matching kinetics entry in any part of
    the database. This means that the same reaction may appear multiple times
    with different kinetics in the output. If the RMG-Java server is running,
    this function will also query it for reactions and kinetics.
    If `only_families` is a list of strings, only those labeled families are 
    used: no libraries and no RMG-Java kinetics are returned.
    """
    from rmgpy.rmg.model import getFamilyLibraryObject
    # get RMG-py reactions
    reactionList = []
    if only_families is None:
        # Not restricted to certain families, so also check libraries.
        reactionList.extend(
            database.kinetics.generateReactionsFromLibraries(
                reactants, products))
    reactionList.extend(
        database.kinetics.generateReactionsFromFamilies(
            reactants, products, only_families=only_families))
    if len(reactants) == 1:
        # if only one reactant, react it with itself bimolecularly, with RMG-py
        # the java version already does this (it includes A+A reactions when you react A)
        reactants2 = [reactants[0], reactants[0]]
        if only_families is None:
            # Not restricted to certain families, so also check libraries.
            reactionList.extend(
                database.kinetics.generateReactionsFromLibraries(
                    reactants2, products))
        reactionList.extend(
            database.kinetics.generateReactionsFromFamilies(
                reactants2, products, only_families=only_families))

    # get RMG-py kinetics
    reactionList0 = reactionList
    reactionList = []
    for reaction in reactionList0:
        # If the reaction already has kinetics (e.g. from a library),
        # assume the kinetics are satisfactory
        if reaction.kinetics is not None:
            reactionList.append(reaction)
        else:
            # Set the reaction kinetics
            # Only reactions from families should be missing kinetics
            assert isinstance(reaction, TemplateReaction)
            # Get all of the kinetics for the reaction
            family = getFamilyLibraryObject(reaction.family)
            kineticsList = family.getKinetics(reaction,
                                              templateLabels=reaction.template,
                                              degeneracy=reaction.degeneracy,
                                              returnAllKinetics=True)
            if family.ownReverse and hasattr(reaction, 'reverse'):
                kineticsListReverse = family.getKinetics(
                    reaction.reverse,
                    templateLabels=reaction.reverse.template,
                    degeneracy=reaction.reverse.degeneracy,
                    returnAllKinetics=True)
                for kinetics, source, entry, isForward in kineticsListReverse:
                    for kinetics0, source0, entry0, isForward0 in kineticsList:
                        if source0 is not None and source is not None and entry0 is entry and isForward != isForward0:
                            # We already have this estimate from the forward direction, so don't duplicate it in the results
                            break
                    else:
                        kineticsList.append(
                            [kinetics, source, entry, not isForward])
                # We're done with the "reverse" attribute, so delete it to save a bit of memory
                delattr(reaction, 'reverse')
            # Make a new reaction object for each kinetics result
            for kinetics, source, entry, isForward in kineticsList:
                if isForward:
                    reactant_species = reaction.reactants[:]
                    product_species = reaction.products[:]
                else:
                    reactant_species = reaction.products[:]
                    product_species = reaction.reactants[:]

                if source == 'rate rules' or source == 'group additivity':
                    rxn = TemplateReaction(
                        reactants=reactant_species,
                        products=product_species,
                        kinetics=kinetics,
                        degeneracy=reaction.degeneracy,
                        reversible=reaction.reversible,
                        family=reaction.family,
                        estimator=source,
                    )
                else:
                    rxn = DepositoryReaction(
                        reactants=reactant_species,
                        products=product_species,
                        kinetics=kinetics,
                        degeneracy=reaction.degeneracy,
                        reversible=reaction.reversible,
                        depository=source,
                        family=reaction.family,
                        entry=entry,
                    )

                reactionList.append(rxn)

    # get RMG-java reactions
    if only_families is None:
        # Not restricted to certain families, so also check RMG-Java.
        rmgJavaReactionList = getRMGJavaKinetics(reactants, products)
    else:
        rmgJavaReactionList = []

    for rxn in itertools.chain(reactionList, rmgJavaReactionList):
        rxn.reactants = [
            Species(molecule=[mol]) if isinstance(mol, Molecule) else mol
            for mol in rxn.reactants
        ]
        rxn.products = [
            Species(molecule=[mol]) if isinstance(mol, Molecule) else mol
            for mol in rxn.products
        ]

    return reactionList, rmgJavaReactionList
Exemplo n.º 3
0
def generateReactions(database, reactants, products=None, only_families=None):
    """
    Generate the reactions (and associated kinetics) for a given set of
    `reactants` and an optional set of `products`. A list of reactions is
    returned, with a reaction for each matching kinetics entry in any part of
    the database. This means that the same reaction may appear multiple times
    with different kinetics in the output. If the RMG-Java server is running,
    this function will also query it for reactions and kinetics.
    If `only_families` is a list of strings, only those labeled families are 
    used: no libraries and no RMG-Java kinetics are returned.
    """
    from rmgpy.rmg.model import getFamilyLibraryObject
    # get RMG-py reactions
    reactionList = []
    if only_families is None:
        # Not restricted to certain families, so also check libraries.
        reactionList.extend(database.kinetics.generateReactionsFromLibraries(reactants, products))
    reactionList.extend(database.kinetics.generateReactionsFromFamilies(reactants, products, only_families=only_families))
    if len(reactants) == 1:
        # if only one reactant, react it with itself bimolecularly, with RMG-py
        # the java version already does this (it includes A+A reactions when you react A)
        reactants2 = [reactants[0], reactants[0]]
        if only_families is None:
            # Not restricted to certain families, so also check libraries.
            reactionList.extend(database.kinetics.generateReactionsFromLibraries(reactants2, products))
        reactionList.extend(database.kinetics.generateReactionsFromFamilies(reactants2, products, only_families=only_families))
    
    # get RMG-py kinetics
    reactionList0 = reactionList; reactionList = []
    for reaction in reactionList0:
        # If the reaction already has kinetics (e.g. from a library),
        # assume the kinetics are satisfactory
        if reaction.kinetics is not None:
            reactionList.append(reaction)
        else:
            # Set the reaction kinetics
            # Only reactions from families should be missing kinetics
            assert isinstance(reaction, TemplateReaction)
            # Get all of the kinetics for the reaction
            family = getFamilyLibraryObject(reaction.family)
            kineticsList = family.getKinetics(reaction, template=reaction.template, degeneracy=reaction.degeneracy, returnAllKinetics=True)
            if family.ownReverse and hasattr(reaction,'reverse'):
                kineticsListReverse = family.getKinetics(reaction.reverse, template=reaction.reverse.template, degeneracy=reaction.reverse.degeneracy, returnAllKinetics=True)
                for kinetics, source, entry, isForward in kineticsListReverse:
                    for kinetics0, source0, entry0, isForward0 in kineticsList:
                        if source0 is not None and source is not None and entry0 is entry and isForward != isForward0:
                            # We already have this estimate from the forward direction, so don't duplicate it in the results
                            break
                    else:
                        kineticsList.append([kinetics, source, entry, not isForward])
                # We're done with the "reverse" attribute, so delete it to save a bit of memory
                delattr(reaction,'reverse')
            # Make a new reaction object for each kinetics result
            for kinetics, source, entry, isForward in kineticsList:
                if isForward:
                    reactant_species = reaction.reactants[:]
                    product_species = reaction.products[:]
                else:
                    reactant_species = reaction.products[:]
                    product_species = reaction.reactants[:]
                
                if source == 'rate rules' or source == 'group additivity':
                    rxn = TemplateReaction(
                        reactants = reactant_species,
                        products = product_species,
                        kinetics = kinetics,
                        degeneracy = reaction.degeneracy,
                        reversible = reaction.reversible,
                        family = reaction.family,
                        estimator = source,
                    )
                else:
                    rxn = DepositoryReaction(
                        reactants = reactant_species,
                        products = product_species,
                        kinetics = kinetics,
                        degeneracy = reaction.degeneracy,
                        reversible = reaction.reversible,
                        depository = source,
                        family = reaction.family,
                        entry = entry,
                    )                    
                    
                reactionList.append(rxn)
    
    # get RMG-java reactions
    if only_families is None:
        # Not restricted to certain families, so also check RMG-Java.
        rmgJavaReactionList = getRMGJavaKinetics(reactants, products)
    else:
        rmgJavaReactionList = []
    
    return reactionList, rmgJavaReactionList
Exemplo n.º 4
0
def generateReactions(database,
                      reactants,
                      products=None,
                      only_families=None,
                      resonance=True):
    """
    Generate the reactions (and associated kinetics) for a given set of
    `reactants` and an optional set of `products`. A list of reactions is
    returned, with a reaction for each matching kinetics entry in any part of
    the database. This means that the same reaction may appear multiple times
    with different kinetics in the output.

    If `only_families` is a list of strings, only those labeled families are 
    used: no libraries and no RMG-Java kinetics are returned.
    """
    from rmgpy.rmg.model import getFamilyLibraryObject
    # get RMG-py reactions
    reaction_list = database.kinetics.generate_reactions(
        reactants, products, only_families=only_families, resonance=resonance)
    if len(reactants) == 1:
        # if only one reactant, react it with itself bimolecularly, with RMG-py
        # the java version already does this (it includes A+A reactions when you react A)
        reactants2 = [reactants[0], reactants[0]]
        reaction_list.extend(
            database.kinetics.generate_reactions(reactants2,
                                                 products,
                                                 only_families=only_families,
                                                 resonance=resonance))

    # get RMG-py kinetics
    reaction_data_list = []
    template_reactions = []
    for reaction in reaction_list:
        # If the reaction already has kinetics (e.g. from a library),
        # assume the kinetics are satisfactory
        if reaction.kinetics is not None:
            reaction_data_list.append(reaction)
        else:
            # Set the reaction kinetics
            # Only reactions from families should be missing kinetics
            assert isinstance(reaction, TemplateReaction)

            # Determine if we've already processed an isomorphic reaction with a different template
            duplicate = False
            for t_rxn in template_reactions:
                if reaction.isIsomorphic(t_rxn):
                    assert set(reaction.template) != set(
                        t_rxn.template
                    ), 'There should not be duplicate reactions with identical templates.'
                    duplicate = True
                    break
            else:
                # We haven't encountered this reaction yet, so add it to the list
                template_reactions.append(reaction)

            # Get all of the kinetics for the reaction
            family = getFamilyLibraryObject(reaction.family)
            kineticsList = family.getKinetics(reaction,
                                              templateLabels=reaction.template,
                                              degeneracy=reaction.degeneracy,
                                              returnAllKinetics=True)
            if family.ownReverse and hasattr(reaction, 'reverse'):
                kineticsListReverse = family.getKinetics(
                    reaction.reverse,
                    templateLabels=reaction.reverse.template,
                    degeneracy=reaction.reverse.degeneracy,
                    returnAllKinetics=True)
                for kinetics, source, entry, isForward in kineticsListReverse:
                    for kinetics0, source0, entry0, isForward0 in kineticsList:
                        if source0 is not None and source is not None and entry0 is entry and isForward != isForward0:
                            # We already have this estimate from the forward direction, so don't duplicate it in the results
                            break
                    else:
                        kineticsList.append(
                            [kinetics, source, entry, not isForward])
                # We're done with the "reverse" attribute, so delete it to save a bit of memory
                delattr(reaction, 'reverse')
            # Make a new reaction object for each kinetics result
            for kinetics, source, entry, isForward in kineticsList:
                if duplicate and source != 'rate rules':
                    # We've already processed this reaction with a different template,
                    # so we only need the new rate rule estimates
                    continue

                if isForward:
                    reactant_species = reaction.reactants[:]
                    product_species = reaction.products[:]
                else:
                    reactant_species = reaction.products[:]
                    product_species = reaction.reactants[:]

                if source == 'rate rules' or source == 'group additivity':
                    rxn = TemplateReaction(
                        reactants=reactant_species,
                        products=product_species,
                        kinetics=kinetics,
                        degeneracy=reaction.degeneracy,
                        reversible=reaction.reversible,
                        family=reaction.family,
                        estimator=source,
                        template=reaction.template,
                    )
                else:
                    rxn = DepositoryReaction(
                        reactants=reactant_species,
                        products=product_species,
                        kinetics=kinetics,
                        degeneracy=reaction.degeneracy,
                        reversible=reaction.reversible,
                        depository=source,
                        family=reaction.family,
                        entry=entry,
                    )

                reaction_data_list.append(rxn)

    return reaction_data_list
Exemplo n.º 5
0
def pathwayGenerator(reactants, products, rmg, only_families):
	genRxn = database.kinetics.generateReactionsFromFamilies

	# LOOP starts
	newReactions = []
	rxt_mol_mutation_num = 1
	pdt_mol_mutation_num = 1
	for reactant in reactants:
		rxt_mol_mutation_num *= len(reactant.molecule)
	for product in products:
		pdt_mol_mutation_num *= len(product.molecule)

	for mutation_i in range(rxt_mol_mutation_num):
		rxts_mol = [spc.molecule[mutation_i%(len(spc.molecule))] for spc in reactants]
		for mutation_j in range(pdt_mol_mutation_num):
			pdts_mol = [spc.molecule[mutation_j%(len(spc.molecule))] for spc in products]

	        newReactions.extend(genRxn(reactants=rxts_mol,\
	            products=pdts_mol, only_families=only_families))

	rmg.reactionModel.newSpeciesList = []
	rmg.reactionModel.newReactionList = []
	rmg.reactionModel.processNewReactions(newReactions, reactants)

	# gen thermo and transport for new species
	for spec in rmg.reactionModel.newSpeciesList:
	    if not spec.hasThermo():
	        spec.generateThermoData(database)
	        spec.generateTransportData(database)

	for reaction in rmg.reactionModel.newReactionList:
	    family = getFamilyLibraryObject(reaction.family)

	    # If the reaction already has kinetics (e.g. from a library),
	    # assume the kinetics are satisfactory
	    if reaction.kinetics is None:
	        # Set the reaction kinetics
	        kinetics, source, entry, isForward = rmg.reactionModel.generateKinetics(reaction)
	        reaction.kinetics = kinetics
	        # Flip the reaction direction if the kinetics are defined in the reverse direction
	        if not isForward:
	            reaction.reactants, reaction.products = reaction.products, reaction.reactants
	            reaction.pairs = [(p,r) for r,p in reaction.pairs]
	        if family.ownReverse and hasattr(reaction,'reverse'):
	            if not isForward:
	                reaction.template = reaction.reverse.template
	            # We're done with the "reverse" attribute, so delete it to save a bit of memory
	            delattr(reaction,'reverse')

	# For new reactions, convert ArrheniusEP to Arrhenius, and fix barrier heights.
	# self.newReactionList only contains *actually* new reactions, all in the forward direction.
	for reaction in rmg.reactionModel.newReactionList:
	    # convert KineticsData to Arrhenius forms
	    if isinstance(reaction.kinetics, KineticsData):
	        reaction.kinetics = reaction.kinetics.toArrhenius()
	    #  correct barrier heights of estimated kinetics
	    if isinstance(reaction,TemplateReaction) or isinstance(reaction,DepositoryReaction): # i.e. not LibraryReaction
	        reaction.fixBarrierHeight() # also converts ArrheniusEP to Arrhenius.

	    if rmg.reactionModel.pressureDependence and reaction.isUnimolecular():
	        # If this is going to be run through pressure dependence code,
	        # we need to make sure the barrier is positive.
	        reaction.fixBarrierHeight(forcePositive=True)