예제 #1
0
def getFluxGraphEdgesDict(spc_rop_dict, core_reactions):
    
    graph_edges_dict = {}
    for rxn in core_reactions:
        for pair in rxn.pairs:
            if pair in graph_edges_dict:
                # get flux from spc_rop_dict
                species_string = getSpeciesIdentifier(pair[0])
                flux = getROPFlux(spc_rop_dict, species_string, rxn.index)
                if len(flux) > 0:
                    graph_edges_dict[pair][rxn] = flux
            elif (pair[1], pair[0]) in graph_edges_dict:
                # get flux from spc_rop_dict
                species_string = getSpeciesIdentifier(pair[1])
                flux = getROPFlux(spc_rop_dict, species_string, rxn.index)
                if len(flux) > 0:
                    graph_edges_dict[(pair[1], pair[0])][rxn] = flux
            else:
                # get flux from spc_rop_dict
                graph_edges_dict[pair] = {}
                species_string = getSpeciesIdentifier(pair[0])
                flux = getROPFlux(spc_rop_dict, species_string, rxn.index)
                if len(flux) > 0:
                    graph_edges_dict[pair][rxn] = flux
    return graph_edges_dict
예제 #2
0
def simulateOne(reactionModel, atol, rtol, reactionSystem):
    """

    Simulates one reaction system, listener registers results, 
    which are returned at the end.


    The returned data consists of a array of the species names, 
    and the concentration data.

    The concentration data consists of a number of elements for each timestep 
    the solver took to reach the end time of the batch reactor simulation.

    Each element consists of the time and the concentration data of the species at that 
    particular timestep in the order of the species names.

    """

    #register as a listener
    listener = ConcentrationListener()

    coreSpecies = reactionModel.core.species
    regex = r'\([0-9]+\)'  #cut of '(one or more digits)'
    speciesNames = []
    for spc in coreSpecies:
        name = getSpeciesIdentifier(spc)
        name_cutoff = re.split(regex, name)[0]
        speciesNames.append(name_cutoff)

    listener.speciesNames = speciesNames

    reactionSystem.attach(listener)

    pdepNetworks = []
    for source, networks in reactionModel.networkDict.items():
        pdepNetworks.extend(networks)

    simulatorSettings = SimulatorSettings(atol, rtol)
    modelSettings = ModelSettings(toleranceKeepInEdge=0,
                                  toleranceMoveToCore=1,
                                  toleranceInterruptSimulation=1)

    terminated, obj, sspcs, srxns = reactionSystem.simulate(
        coreSpecies=reactionModel.core.species,
        coreReactions=reactionModel.core.reactions,
        edgeSpecies=reactionModel.edge.species,
        edgeReactions=reactionModel.edge.reactions,
        surfaceSpecies=[],
        surfaceReactions=[],
        pdepNetworks=pdepNetworks,
        modelSettings=modelSettings,
        simulatorSettings=simulatorSettings,
    )

    assert terminated

    #unregister as a listener
    reactionSystem.detach(listener)

    return listener.speciesNames, listener.data
예제 #3
0
    def update(self, reactionSystem):
        """
        Opens a file with filename referring to:
            - reaction system
            - number of core species

        Writes to a csv file:
            - header row with species names
            - each row with mole fractions of the core species in the given reaction system.
        """

        filename = os.path.join(
            self.outputDirectory, 'solver',
            'simulation_{0}_{1:d}.csv'.format(self.reaction_sys_index + 1,
                                              len(self.coreSpecies)))

        header = ['Time (s)', 'Volume (m^3)']
        for spc in self.coreSpecies:
            header.append(getSpeciesIdentifier(spc))

        with open(filename, 'wb') as csvfile:
            worksheet = csv.writer(csvfile)

            # add header row:
            worksheet.writerow(header)

            # add mole fractions:
            worksheet.writerows(reactionSystem.snapshots)
예제 #4
0
    def update(self, reactionSystem):
        """
        Opens a file with filename referring to:
            - reaction system
            - number of core species

        Writes to a csv file:
            - header row with species names
            - each row with mole fractions of the core species in the given reaction system.
        """

        filename = os.path.join(
            self.outputDirectory,
            'solver',
            'simulation_{0}_{1:d}.csv'.format(
                self.reaction_sys_index + 1, len(self.coreSpecies)
                )
            )

        header = ['Time (s)', 'Volume (m^3)']
        for spc in self.coreSpecies:
            header.append(getSpeciesIdentifier(spc))

        with open(filename, 'w') as csvfile:
            worksheet = csv.writer(csvfile)

            # add header row:
            worksheet.writerow(header) 

            # add mole fractions:
            worksheet.writerows(reactionSystem.snapshots)
예제 #5
0
파일: reduction.py 프로젝트: cainja/RMG-Py
def simulateOne(reactionModel, atol, rtol, reactionSystem):
    """

    Simulates one reaction system, listener registers results, 
    which are returned at the end.


    The returned data consists of a array of the species names, 
    and the concentration data.

    The concentration data consists of a number of elements for each timestep 
    the solver took to reach the end time of the batch reactor simulation.

    Each element consists of the time and the concentration data of the species at that 
    particular timestep in the order of the species names.

    """

    #register as a listener
    listener = ConcentrationListener()

    coreSpecies = reactionModel.core.species
    regex = r'\([0-9]+\)'#cut of '(one or more digits)'
    speciesNames = []
    for spc in coreSpecies:
        name = getSpeciesIdentifier(spc)
        name_cutoff = re.split(regex, name)[0]
        speciesNames.append(name_cutoff)

    listener.speciesNames = speciesNames

    reactionSystem.attach(listener)

    pdepNetworks = []
    for source, networks in reactionModel.networkDict.items():
        pdepNetworks.extend(networks)
        
    simulatorSettings = SimulatorSettings(atol,rtol)
    modelSettings = ModelSettings(toleranceKeepInEdge=0,toleranceMoveToCore=1,toleranceInterruptSimulation=1)
    
    terminated,resurrected,obj,sspcs,srxns = reactionSystem.simulate(
        coreSpecies = reactionModel.core.species,
        coreReactions = reactionModel.core.reactions,
        edgeSpecies = reactionModel.edge.species,
        edgeReactions = reactionModel.edge.reactions,
        surfaceSpecies = [],
        surfaceReactions = [],
        pdepNetworks = pdepNetworks,
        modelSettings = modelSettings,
        simulatorSettings=simulatorSettings,
    ) 

    assert terminated

    #unregister as a listener
    reactionSystem.detach(listener) 

    return listener.speciesNames, listener.data
예제 #6
0
파일: ignition.py 프로젝트: nyee/PyChemkin
def runIgnitionThermoSensitivity(runChemkinJob, inputFile, dictionaryFile):
    """
    Supply a runChemkinJob python function which returns the ignition delay with a 
    chemkin file input.  This will run finite difference sensitivities to enthalpies and 
    save them to a csv file.
    """

    from rmgpy.chemkin import loadChemkinFile, saveChemkinFile, getSpeciesIdentifier
    from rmgpy.quantity import Quantity

    speciesList, reactionList = loadChemkinFile(inputFile,
                                                dictionaryPath=dictionaryFile,
                                                readComments=False)

    num_species = len(speciesList)

    deltaH = Quantity(0.5, 'kcal/mol').value_si

    worksheet = csv.writer(file('ignition_thermo_sensitivity.csv', 'w'))
    worksheet.writerow([
        'Species', 'd[del H] (kcal/mol)', 'tau_high', 'tau_low',
        'd[ln tau]/d[del H]'
    ])

    print 'Running thermo sensitivity analysis using finite differences...'
    for index, species in enumerate(speciesList):
        species_index = index + 1
        species_string = getSpeciesIdentifier(species)
        print 'At species {0} of {1}. {2}'.format(species_index, num_species,
                                                  species_string)

        species.thermo.changeBaseEnthalpy(deltaH)
        saveChemkinFile('chem_temp.inp',
                        speciesList,
                        reactionList,
                        verbose=False)
        tau_high = runChemkinJob('chem_temp.inp')
        species.thermo.changeBaseEnthalpy(-deltaH)  # reset the thermo

        species.thermo.changeBaseEnthalpy(-deltaH)
        saveChemkinFile('chem_temp.inp',
                        speciesList,
                        reactionList,
                        verbose=False)
        tau_low = runChemkinJob('chem_temp.inp')
        species.thermo.changeBaseEnthalpy(deltaH)  # reset the kinetics

        if tau_high != 0 and tau_low != 0:
            sens = numpy.log(tau_high / tau_low) / (2 * deltaH)
        else:
            sens = 0

        worksheet.writerow([species_string, '1', tau_high, tau_low, sens])
예제 #7
0
def renderSpecies(species, thermo=False):
    speciesLabel = getSpeciesIdentifier(species)
    speciesHTML = """
<tr class="species">
    <td class="label">{label}</td>
    <td class="structure"><a href={url}><img src="species/{filename}" alt="{label}" title="{label}"></a></td>
    <td class="smiles">{smiles}</td>
""".format(
           url=species.molecule[0].getURL(),
           filename=speciesLabel+'.png',
           label=speciesLabel,
           smiles=species.molecule[0].toSMILES(),
           )


    if thermo:
        thermo = species.thermo
        speciesHTML += """<td class="thermo">
        <table align="center">
            <tr>
                <th>H298</th>
                <th>S298</th>
                <th>Cp300</th>
                <th>Cp500</th>
                <th>Cp1000</th>
                <th>Cp1500</th>
            </tr>
            <tr>
                <td>{H298:.2f}</td>
                <td>{S298:.2f}</td>
                <td>{Cp300:.2f}</td>
                <td>{Cp500:.2f}</td>
                <td>{Cp1000:.2f}</td>
                <td>{Cp1500:.2f}</td>
            </tr>
            <tr class="comment"><th colspan=6>Comments</th></tr>
            <tr class="comment"><td colspan=6>{comments}</td></tr>
        </table></td>
""".format(H298=thermo.getEnthalpy(298)/4184,
           S298=thermo.getEntropy(298)/4.184,
           Cp300=thermo.getHeatCapacity(300)/4.184,
           Cp500=thermo.getHeatCapacity(300)/4.184,
           Cp1000=thermo.getHeatCapacity(300)/4.184,
           Cp1500=thermo.getHeatCapacity(300)/4.184, 
           comments=thermo.comment)

    speciesHTML += """</tr>"""
    
    return speciesHTML
예제 #8
0
def runIgnitionThermoSensitivity(runChemkinJob, inputFile, dictionaryFile):
    """
    Supply a runChemkinJob python function which returns the ignition delay with a 
    chemkin file input.  This will run finite difference sensitivities to enthalpies and 
    save them to a csv file.
    """
    
    from rmgpy.chemkin import loadChemkinFile, saveChemkinFile, getSpeciesIdentifier
    from rmgpy.quantity import Quantity
    
    
    speciesList, reactionList = loadChemkinFile(inputFile, dictionaryPath = dictionaryFile, readComments = False)
    
    num_species = len(speciesList)
    
    deltaH = Quantity(0.5, 'kcal/mol').value_si
    
    worksheet = csv.writer(file('ignition_thermo_sensitivity.csv', 'w'))
    worksheet.writerow(['Species', 'd[del H] (kcal/mol)', 'tau_high', 'tau_low', 'd[ln tau]/d[del H]'])
    
    logging.info('Running thermo sensitivity analysis using finite differences...')
    for index, species in enumerate(speciesList):
        species_index = index + 1
        species_string = getSpeciesIdentifier(species)
        logging.info('At species {0} of {1}. {2}'.format(species_index, num_species, species_string))
        
        species.thermo.changeBaseEnthalpy(deltaH)
        saveChemkinFile('chem_temp.inp', speciesList, reactionList, verbose = False)
        tau_high = runChemkinJob('chem_temp.inp')
        species.thermo.changeBaseEnthalpy(-deltaH)    # reset the thermo
        
        species.thermo.changeBaseEnthalpy(-deltaH)
        saveChemkinFile('chem_temp.inp', speciesList, reactionList, verbose = False)
        tau_low = runChemkinJob('chem_temp.inp')
        species.thermo.changeBaseEnthalpy(deltaH)     # reset the kinetics
        
        if tau_high != 0 and tau_low != 0:
            sens = numpy.log(tau_high / tau_low) / (2 * deltaH)
        else:
            sens = 0
            
        worksheet.writerow([species_string, '1', tau_high, tau_low, sens])
예제 #9
0
def getFluxGraphEdgesDict(spc_rop_dict, core_reactions):

    graph_edges_dict = {}
    for rxn in core_reactions:
        for pair in rxn.pairs:
            if pair in graph_edges_dict:
                # get flux from spc_rop_dict
                species_string = getSpeciesIdentifier(pair[0])
                flux = getROPFlux(spc_rop_dict, species_string, rxn.index)
                if len(flux) > 0:
                    graph_edges_dict[pair][rxn] = flux
                else:
                    # for rxns like PDD + rad4 == PDD + rad1
                    species_string = getSpeciesIdentifier(pair[1])
                    flux = getROPFlux(spc_rop_dict, species_string, rxn.index)
                    if len(flux) > 0:
                        graph_edges_dict[pair][rxn] = -flux
            elif (pair[1], pair[0]) in graph_edges_dict:
                # get flux from spc_rop_dict
                species_string = getSpeciesIdentifier(pair[1])
                flux = getROPFlux(spc_rop_dict, species_string, rxn.index)
                if len(flux) > 0:
                    graph_edges_dict[(pair[1], pair[0])][rxn] = flux
                else:
                    species_string = getSpeciesIdentifier(pair[0])
                    flux = getROPFlux(spc_rop_dict, species_string, rxn.index)
                    if len(flux) > 0:
                        graph_edges_dict[(pair[1], pair[0])][rxn] = -flux
            else:
                # get flux from spc_rop_dict
                graph_edges_dict[pair] = {}
                species_string = getSpeciesIdentifier(pair[0])
                flux = getROPFlux(spc_rop_dict, species_string, rxn.index)
                if len(flux) > 0:
                    graph_edges_dict[pair][rxn] = flux
                else:
                    species_string = getSpeciesIdentifier(pair[1])
                    flux = getROPFlux(spc_rop_dict, species_string, rxn.index)
                    if len(flux) > 0:
                        graph_edges_dict[pair][rxn] = -flux
    return graph_edges_dict
예제 #10
0
def renderReactionROP(reactionROP, speciesList, showROP = True, idx=0):
    
    reaction = reactionROP.rxnObject
    
    reactionHTML = """
    <tr class="reaction"><th><a href="{url}" title="Search on RMG website" class="searchlink">{index}.</a> {rxnString}</th>
    """.format(rxnString=reaction.toChemkin(speciesList, kinetics=False), url=reaction.getURL(), index=reaction.index)
    
    if showROP:
        reactionHTML += """<td>Flux = {flux}</td>
        <td>Flux % = {percent}</td>""".format(flux=reactionROP.data[idx], percent=reactionROP.fluxPercentage[idx])
    reactionHTML += """</tr>"""
    
    reactantsHTML = []
    for reactant in reaction.reactants:
        reactantsHTML.append('<a href="{mol_url}"><img src="species/{label}.png" alt="{label}" title="{label}"></a>'.format(
                                                                                                                            mol_url=reactant.molecule[0].getURL(),
                                                                                                                            label=getSpeciesIdentifier(reactant),
                                                                                                                            ))
        
    reactionHTML += """<tr><td class="reactants">"""
    reactionHTML += ' + '.join(reactantsHTML)
    reactionHTML += """</td>"""
    
    reactionHTML += """<td class="reactionArrow">"""    
    if reaction.reversible:
        reactionHTML +="&hArr;"
    else:
        reactionHTML += "&rarr;"
    reactionHTML += """</td>"""
    
    productsHTML = []
    for product in reaction.products:
        productsHTML.append('<a href="{mol_url}"><img src="species/{label}.png" alt="{label}" title="{label}"></a>'.format(
                                                                                                                            mol_url=product.molecule[0].getURL(),
                                                                                                                            label=getSpeciesIdentifier(product),
                                                                                                                            ))
    
    reactionHTML += """<td class="products">"""
    reactionHTML += ' + '.join(productsHTML)
    reactionHTML += """</td></tr>"""
#    reactionHTML += """
#    <td class="family">{source}</td></tr>
#    """.format(source=reaction.getSource().label)
    
#    reactionHTML +="""
#    <tr class="kinetics">
#    <td colspan="4">{kinetics}</td>
#    </tr>""".format(kinetics=reaction.kinetics.toHTML())
    
    reactionHTML += """
    <tr class="chemkin">
    <th>CHEMKIN String</th></tr>
    <tr class="chemkin">
    <td>{chemkin}</td>
    </tr>
""".format(
           chemkin=reaction.toChemkin(speciesList)
           )

    return reactionHTML
예제 #11
0
파일: flux.py 프로젝트: KEHANG/PyChemkin
def extractROPData(ckcsvFile, species="", speciesList=[], reactionList=[]):
    """
    Extract the ROP information from a chemkin run for a single species.
    Returns a list of SpeciesROP objects. Will only return a list containing a single SpeciesROP object
    if there are no continuations.
    
    Will also identify corresponding species and reaction objects from a loaded Chemkin file if 
    speciesList and reactionList are given.
    """
    from rmgpy.chemkin import getSpeciesIdentifier

    # Pre-convert the speciesList and reactionList to strings
    speciesStringList = []
    if speciesList:
        for spec in speciesList:
            speciesStringList.append(getSpeciesIdentifier(spec))

    reactionStringList = []
    if reactionList:
        for rxn in reactionList:
            rxnString = rxn.toChemkin(kinetics=False)
            if rxn.reversible:
                rxnString = rxnString.replace("=", "<=>")
            reactionStringList.append(rxnString)

    timeData = {}
    distanceData = {}
    speciesROPData = {}

    with open(ckcsvFile, "r") as stream:
        reader = csv.reader(stream)

        for row in reader:
            label = row[0].strip()
            tokens = label.split("_")
            if tokens[0] == "Time":
                if "Soln" in tokens[-1]:
                    tsolnNumber = int(tokens[-1].split("#")[-1])
                else:
                    tsolnNumber = 0
                tdata = numpy.array([float(r) for r in row[2:]], numpy.float)
                tunits = row[1].strip()[1:-1].lower()
                tdata *= {"sec": 1.0, "min": 60.0, "hr": 3600.0, "msec": 1e-3, "microsec": 1e-6}[tunits]
                timeData[tsolnNumber] = tdata
                continue

            if tokens[0] == "Distance":
                if "Soln" in tokens[-1]:
                    dsolnNumber = int(tokens[-1].split("#")[-1])
                else:
                    dsolnNumber = 0
                ddata = numpy.array([float(r) for r in row[2:]], numpy.float)
                dunits = row[1].strip()[1:-1].lower()
                ddata *= {"cm": 1.0, "mm": 0.1, "m": 100.0}[dunits]
                distanceData[dsolnNumber] = ddata
                continue

            if len(tokens) > 1:
                if tokens[1] == "ROP":
                    species_string = tokens[0]
                    if species == species_string:
                        # Create a SpeciesROP object for this solution number
                        if "Soln" in tokens[-1]:
                            solutionNumber = int(tokens[-1].split("#")[-1])
                        else:
                            # Only 1 solution set
                            solutionNumber = 0
                        if solutionNumber not in speciesROPData.keys():
                            speciesROPData[solutionNumber] = SpeciesROP(species, ropData=[])
                            if speciesList:
                                speciesROPData[solutionNumber].identifySpecies(speciesList, speciesStringList)
                        if tokens[3] == "Total":
                            # Total ROP rate
                            speciesROPData[solutionNumber].totalRopData = numpy.array(
                                [float(r) for r in row[2:]], numpy.float
                            )
                        else:
                            rxnString = tokens[2]
                            rxnNumber = int(tokens[3].split("#")[-1])
                            rxnRopData = numpy.array([float(r) for r in row[2:]], numpy.float)
                            dataObject = ReactionROP(rxnString=rxnString, rxnNumber=rxnNumber, data=rxnRopData)
                            if reactionList:
                                dataObject.identifyReaction(reactionList, reactionStringList)
                            speciesROPData[solutionNumber].ropData.append(dataObject)

    speciesROPList = []
    if timeData:
        if len(timeData) != len(speciesROPData):
            raise Exception("Number of time and ROP data sets are mismatched.  Something went wrong during parsing")
        else:
            for solutionNumber in sorted(speciesROPData.keys()):
                speciesROP = speciesROPData[solutionNumber]
                speciesROP.xvarData = timeData[solutionNumber]
                speciesROPList.append(speciesROP)

    elif distanceData:
        if len(distanceData) != len(speciesROPData):
            raise Exception("Number of time and ROP data sets are mismatched.  Something went wrong during parsing")
        else:
            for solutionNumber in sorted(speciesROPData.keys()):
                speciesROP = speciesROPData[solutionNumber]
                speciesROP.xvarData = distanceData[solutionNumber]
                speciesROPList.append(speciesROP)

    else:
        raise Exception("Did not parse any time or distance data.  Something went wrong during parsing or simulation")

    return speciesROPList
예제 #12
0
파일: flux.py 프로젝트: KEHANG/PyChemkin
def saveFluxAnalysisHTML(path, idx, speciesROP, negativeROPList=[], positiveROPList=[], speciesList=[]):
    """
    Save the flux analysis for a given species to HTML.
    """
    import os
    from rmgpy.molecule.draw import MoleculeDrawer
    from rmgpy.chemkin import getSpeciesIdentifier
    from .html import renderSpecies, renderReactionROP, STYLE_HEADER

    try:
        import jinja2
    except ImportError:
        print "jinja2 package not found; HTML output will not be saved."
        return

    path = os.path.abspath(path)
    dirname = os.path.dirname(path)

    if not os.path.isdir(os.path.join(dirname, "species")):
        os.makedirs(os.path.join(dirname, "species"))

    for spec in speciesList:
        # Draw molecules
        speciesLabel = getSpeciesIdentifier(spec)
        fstr = os.path.join(dirname, "species", "{0}.png".format(speciesLabel))
        if not os.path.exists(fstr):
            try:
                MoleculeDrawer().draw(spec.molecule[0], "png", fstr)
            except IndexError:
                raise Exception(
                    "{0} species could not be drawn because it did not contain a molecular structure. Please recheck your files.".format(
                        speciesLabel
                    )
                )

    # title = 'Flux Analysis for Species {label} at x = {x}'.format(label=getSpeciesIdentifier(species), x=speciesROP.xvarData[idx])
    # self.totalNegativeRate[idx]
    # print '{num}. {rxnString}\t Actual flux = {flux}\t % of Total Positive ROP = {fluxpercent}'.format(num=i+1, rxnString=rxnRop.rxnString, flux=rxnRop.data[idx], fluxpercent=rxnRop.fluxPercentage[idx])

    environment = jinja2.Environment()
    environment.filters["renderSpecies"] = renderSpecies
    environment.filters["renderReactionROP"] = renderReactionROP
    environment.filters["getSpeciesIdentifier"] = getSpeciesIdentifier

    # Make HTML file
    template = environment.from_string(
        """<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
<title>Flux Analysis for Species {{speciesROP.speciesObject|getSpeciesIdentifier}} at x = {{speciesROP.xvarData[idx]}}</title>
{{style}}
</head>
<body>
<h1>Flux Analysis for Species {{speciesROP.speciesObject|getSpeciesIdentifier}} at x = {{speciesROP.xvarData[idx]}}</h1>
<h2>Species</h2>

<table class="speciesList">
<tr><th>Label</th><th>Structure</th><th>SMILES</th><th>Thermo</th>
{{speciesROP.speciesObject|renderSpecies(thermo=True)}}
</table>
<hr>

<h3>Net ROP = {{speciesROP.totalRopData[idx]}}</h3>

<hr size=3>
<h2>Top Negative Flux Reactions Depleting Species {{speciesROP.speciesObject|getSpeciesIdentifier}}</h2>
<h3>Total Negative ROP = {{speciesROP.totalNegativeRate[idx]}}</h3>

<table class="reactionList" hide_comment hide_kinetics hide_chemkin">
{% for rxnROP in negativeROPList %}
{{rxnROP|renderReactionROP(speciesList, showROP=True, idx=idx)}}
{% endfor %}
</table>

<hr size=3>
<h2>Top Positive Flux Reactions Accumulating Species {{speciesROP.speciesObject|getSpeciesIdentifier}}</h2>
<h3>Total Positive ROP = {{speciesROP.totalPositiveRate[idx]}}</h3>

<table class="reactionList" hide_comment hide_kinetics hide_chemkin">
{% for rxnROP in positiveROPList %}
{{rxnROP|renderReactionROP(speciesList, showROP=True, idx=idx)}}
{% endfor %}
</table>

</body>
</html>
"""
    )

    f = open(path, "w")
    f.write(
        template.render(
            style=STYLE_HEADER,
            idx=idx,
            speciesROP=speciesROP,
            negativeROPList=negativeROPList,
            positiveROPList=positiveROPList,
            speciesList=speciesList,
        )
    )
    f.close()
예제 #13
0
 def toChemkin(self):
     """
     Return the chemkin-formatted string for this species.
     """
     from rmgpy.chemkin import getSpeciesIdentifier
     return getSpeciesIdentifier(self)
예제 #14
0
 def toChemkin(self):
     """
     Return the chemkin-formatted string for this species.
     """
     from rmgpy.chemkin import getSpeciesIdentifier
     return getSpeciesIdentifier(self)
예제 #15
0
    def simulate(self):
        """
        Run all the conditions as a cantera simulation.
        Returns the data as a list of tuples containing: (time, [list of temperature, pressure, and species data]) 
            for each reactor condition
        """
        # Get all the cantera names for the species
        speciesNamesList = [getSpeciesIdentifier(species) for species in self.speciesList]

        
        allData = []
        for condition in self.conditions:

            # First translate the molFrac from species objects to species names
            newMolFrac = {}
            for key, value in condition.molFrac.iteritems():
                newkey = getSpeciesIdentifier(key)
                newMolFrac[newkey] = value

            # Set Cantera simulation conditions
            if condition.V0 is None:
                self.model.TPX = condition.T0.value_si, condition.P0.value_si, newMolFrac
            elif condition.P0 is None:
                self.model.TDX = condition.T0.value_si, 1.0/condition.V0.value_si, newMolFrac
            else:
                raise Exception("Cantera conditions in which T0 and P0 or T0 and V0 are not the specified state variables are not yet implemented.")


            # Choose reactor
            if condition.reactorType == 'IdealGasReactor':
                canteraReactor=ct.IdealGasReactor(self.model)
            elif condition.reactorType == 'IdealGasConstPressureReactor':
                canteraReactor=ct.IdealConstPressureGasReactor(self.model)
            else:
                raise Exception('Other types of reactor conditions are currently not supported')
            
            # Run this individual condition as a simulation
            canteraSimulation=ct.ReactorNet([canteraReactor])

            # Initialize the variables to be saved
            times=[]
            temperature=[]
            pressure=[]
            speciesData=[]
            
            # Begin integration
            time = 0.0
            # Run the simulation over 100 time points
            while canteraSimulation.time<condition.reactionTime.value_si:

                # Advance the state of the reactor network in time from the current time to time t [s], taking as many integrator timesteps as necessary.
                canteraSimulation.step(condition.reactionTime.value_si)
                times.append(canteraSimulation.time)
                temperature.append(canteraReactor.T)
                pressure.append(canteraReactor.thermo.P)
                speciesData.append(canteraReactor.thermo[speciesNamesList].X)

            # Convert speciesData to a numpy array
            speciesData=np.array(speciesData)

            # Resave data into generic data objects
            time = GenericData(label = 'Time', 
                               data = times,
                               units = 's')
            temperature = GenericData(label='Temperature',
                                      data = temperature,
                                      units = 'K')
            pressure = GenericData(label='Pressure',
                                      data = pressure,
                                      units = 'Pa')
            conditionData = []
            conditionData.append(temperature)
            conditionData.append(pressure)
            
            for index, species in enumerate(self.speciesList):
                # Create generic data object that saves the species object into the species object.  To allow easier manipulate later.
                speciesGenericData = GenericData(label=speciesNamesList[index],
                                          species = species,
                                          data = speciesData[:,index],
                                          index = species.index
                                          )
                conditionData.append(speciesGenericData)
            
            allData.append((time,conditionData))
            
        return allData
예제 #16
0
파일: output.py 프로젝트: olusade/RMG-Py
def saveOutputHTML(path, reactionModel, partCoreEdge='core'):
    """
    Save the current set of  species and reactions of `reactionModel` to
    an HTML file `path` on disk. As part of this process, drawings of all 
    species are created in the species folder (if they don't already exist)
    using the :mod:`rmgpy.molecule.draw` module. The :mod:`jinja`
    package is used to generate the HTML; if this package is not found, no
    HTML will be generated (but the program will carry on).
    """

    from model import PDepReaction

    from rmgpy.molecule.draw import MoleculeDrawer
    from rmgpy.chemkin import getSpeciesIdentifier

    try:
        import jinja2
    except ImportError:
        logging.warning(
            "jinja2 package not found; HTML output will not be saved.")
        return

    path = os.path.abspath(path)
    dirname = os.path.dirname(path)

    # Prepare parameters to pass to jinja template
    title = 'RMG Output'

    if partCoreEdge == 'core':
        species = reactionModel.core.species[:] + reactionModel.outputSpeciesList
        if not os.path.isdir(os.path.join(dirname, 'species')):
            os.makedirs(os.path.join(dirname, 'species'))
    elif partCoreEdge == 'edge':
        species = reactionModel.edge.species[:] + reactionModel.outputSpeciesList
        if not os.path.isdir(os.path.join(dirname, 'species_edge')):
            os.makedirs(os.path.join(dirname, 'species_edge'))

    re_index_search = re.compile(r'\((\d+)\)$').search

    for spec in species:
        # if the species dictionary came from an RMG-Java job, make them prettier
        # We use the presence of a trailing index on the label to discern this
        # (A single open parenthesis is not enough (e.g. when using SMILES strings as labels!)
        match = re_index_search(spec.label)
        if match:
            spec.index = int(match.group(0)[1:-1])
            spec.label = spec.label[0:match.start()]
        # Draw molecules if necessary
        if partCoreEdge == 'core':
            fstr = os.path.join(dirname, 'species', '{0}.png'.format(spec))
        elif partCoreEdge == 'edge':
            fstr = os.path.join(dirname, 'species_edge',
                                '{0}.png'.format(spec))
        if not os.path.exists(fstr):
            try:
                MoleculeDrawer().draw(spec.molecule[0], 'png', fstr)
            except IndexError:
                raise OutputError(
                    "{0} species could not be drawn because it did not contain a molecular structure. Please recheck your files."
                    .format(getSpeciesIdentifier(spec)))

    # We want to keep species sorted in the original order in which they were added to the RMG core.
    # Rather than ordered by index


#    species.sort(key=lambda x: x.index)

    if partCoreEdge == 'core':
        reactions = [rxn for rxn in reactionModel.core.reactions
                     ] + reactionModel.outputReactionList
    elif partCoreEdge == 'edge':
        reactions = [rxn for rxn in reactionModel.edge.reactions
                     ] + reactionModel.outputReactionList

    # We want to keep reactions sorted in original order in which they were added to core
    # rather than ordered by index
    #reactions.sort(key=lambda x: x.index)

    familyCount = {}
    for rxn in reactions:

        if isinstance(rxn, PDepReaction):
            family = "PDepNetwork"
        else:
            family = rxn.getSource().label
        if family in familyCount:
            familyCount[family] += 1
        else:
            familyCount[family] = 1
    families = familyCount.keys()
    families.sort()

    ## jinja2 filters etc.
    to_remove_from_css_names = re.compile('[/.\-+,]')

    def csssafe(input):
        "Replace unsafe CSS class name characters with an underscore."
        return to_remove_from_css_names.sub('_', input)

    environment = jinja2.Environment()
    environment.filters['csssafe'] = csssafe

    # Make HTML file
    if partCoreEdge == 'core':
        template = environment.from_string(
            """<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
    <title>{{ title }}</title>
    <style type="text/css">
        body {
            font-family: sans-serif;
        }
        a {
            color: #993333;
            text-decoration: none;
        }
        a:visited {
            color: #993333;
        }
        a:hover {
            text-decoration: underline;
        }
        table.speciesList, table.reactionList {
            width: 100%;
            border-collapse: collapse;
        }
        table.speciesList th, table.reactionList th {
            text-align: left;
        }
        tr.reaction td {
            border-top: 1px solid #808080;
        }
        td.reactants {
            text-align: right;
        }
        td.products {
            text-align: left;
        }
        td.reactionArrow {
            text-align: center;
            font-size: 16px;
        }
        td.species img, td.reactants img, td.products img {
            vertical-align: middle;
        }
        tr.comment {
            font-size: small;
        }
        tr.kinetics {
            font-size: small;
        }
        .KineticsData {
            # border: 1px solid gray;
        }
        .KineticsData th {
            width: 15em;
            word-wrap: none;
        }
        .KineticsData td {
            width: 3em;
        }
        
        .chemkin, .KineticsData_repr {
           white-space: pre-wrap;
           font-size: x-small;
           font-family: "Andale Mono", monospace;
        }
        
        .hide_comment .comment{
            display: none !important;
        }
        .hide_kinetics .kinetics{
           display: none !important;
        }
        .hide_chemkin .chemkin{
           display: none !important;
        }
    </style>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.1/jquery.min.js"></script>
    <script type="text/javascript" src="../../../external/jquery.min.js"></script>
    <script type="text/javascript">
    function updateFamily(family) {
        if (family.checked) {
            $("."+family.value).show();
        } else {
            $("."+family.value).hide();
        }
    }
    function updateDetails(type) {
        if (type.checked) {
            $(".reactionList").removeClass("hide_"+type.value);
        } else {
            $(".reactionList").addClass("hide_"+type.value);
        }
    }
    function checkAllFamilies() {
        $("#familySelector").find("[name='family']").each(function() { this.checked = true; updateFamily(this); });
        return false;
    }
    function uncheckAllFamilies() {
        $("#familySelector").find("[name='family']").each(function() { this.checked = false; updateFamily(this); });
        return false;
    }
    function checkAllDetails() {
        $("#familySelector").find("[name='detail']").each(function() { this.checked = true; updateDetails(this); });
        return false;
    }
    function uncheckAllDetails() {
        $("#familySelector").find("[name='detail']").each(function() { this.checked = false; updateDetails(this); });
        return false;
    }
    $(document).ready(function() {
        checkAllFamilies();
        uncheckAllDetails();
    });

    </script>
</head>

<body>

<h1>{{ title }}</h1>

<h2>Species ({{ species|length }})</h2>

<table class="speciesList">
    <tr><th>Index</th><th>Structure</th><th>Label</th><th>Mol. Wt. (g/mol)</th></tr>
    {% for spec in species %}
    <tr class="species">
        <td class="index">
        {{ spec.index }}.</td>
        
        
        
        <td class="structure"><a href={{ spec.molecule[0].getURL() }}><img src="species/{{ spec|replace('#','%23') }}.png" alt="{{ spec }}" title="{{ spec }}"></a></td>
        <td class="label">{{ spec.label }}</td>
        <td>{{ "%.2f"|format(spec.molecule[0].getMolecularWeight() * 1000) }}</td>
    </tr>
    {% if spec.thermo %}
    
    <tr>
     <td>
            <table align="center">
                <tr>
                    <th>H298</th>
                    <th>S298</th>
                    <th>Cp300</th>
                    <th>Cp500</th>
                    <th>Cp1000</th>
                    <th>Cp1500</th>
                </tr>
                <tr>
                    <td>
                    {% if spec.thermo.Tmin.value_si <= 298 %}                    
                    {{ "%.2f"|format(spec.thermo.getEnthalpy(298) / 4184) }}
                    {% endif %} </td>
                    <td>{% if spec.thermo.Tmin.value_si <= 298 %}
                    {{ "%.2f"|format(spec.thermo.getEntropy(298) / 4.184) }}
                    {% endif %}</td>
                    <td>{{ "%.2f"|format(spec.thermo.getHeatCapacity(300) / 4.184) }}</td>
                    <td>{{ "%.2f"|format(spec.thermo.getHeatCapacity(500) / 4.184) }}</td>
                    <td>{{ "%.2f"|format(spec.thermo.getHeatCapacity(1000) / 4.184) }}</td>
                    <td>{{ "%.2f"|format(spec.thermo.getHeatCapacity(1500) / 4.184) }}</td>
                </tr>
            </table>
        </td></tr>
        
        {% endif %}
    {% endfor %}
</table>

<h2>Reactions ({{ reactions|length }})</h2>

<form id='familySelector' action="">
    <h4>Reaction families:</h4>
{% for family in families %}    <input type="checkbox" id="{{ family|csssafe }}" name="family" value="{{ family|csssafe }}" checked="checked" onclick="updateFamily(this);"><label for="{{ family|csssafe }}">{{ family }} ({{ familyCount[family] }} rxn{{ 's' if familyCount[family] != 1 }})</label><br>
{% endfor %}
    <a href="javascript:checkAllFamilies();" onclick="checkAllFamilies()">check all</a> &nbsp; &nbsp; <a href="javascript:uncheckAllFamilies();" onclick="uncheckAllFamilies();">uncheck all</a><br>

    <h4>Reaction Details:</h4>
    <input type="checkbox" id="kinetics" name="detail" value="kinetics" onclick="updateDetails(this);"><label for="kinetics">Kinetics</label><br>
    <input type="checkbox" id="comment" name="detail" value="comment" onclick="updateDetails(this);"><label for="comment">Comments</label><br>
    <input type="checkbox" id="chemkin" name="detail" value="chemkin" onclick="updateDetails(this);"><label for="chemkin">Chemkin strings</label><br>
    <a href="javascript:checkAllDetails();" onclick="checkAllDetails()">check all</a> &nbsp; &nbsp; <a href="javascript:uncheckAllDetails();" onclick="uncheckAllDetails();">uncheck all</a>
</form>

<h4>Reaction List:</h4>

<table class="reactionList hide_comment hide_kinetics hide_chemkin">
    <tr><th>Index</th><th colspan="3" style="text-align: center;">Reaction</th><th>Family</th></tr>
    {% for rxn in reactions %}
    <tr class="reaction {{ rxn.getSource().label|csssafe }}">
        <td class="index"><a href="{{ rxn.getURL() }}" title="Search on RMG website" class="searchlink">{{ rxn.index }}.</a></td>
        <td class="reactants">{% for reactant in rxn.reactants %}<a href="{{ reactant.molecule[0].getURL() }}"><img src="species/{{ reactant|replace('#','%23') }}.png" alt="{{ reactant }}" title="{{ reactant }}, MW = {{ "%.2f g/mol"|format(reactant.molecule[0].getMolecularWeight() * 1000) }}"></a>{% if not loop.last %} + {% endif %}{% endfor %}</td>
        <td class="reactionArrow">{% if rxn.reversible %}&hArr;{% else %}&rarr;{% endif %}</td>
        <td class="products">{% for product in rxn.products %}<a href="{{ product.molecule[0].getURL() }}"><img src="species/{{ product|replace('#','%23') }}.png" alt="{{ product }}" title="{{ product }}, MW = {{ "%.2f g/mol"|format(product.molecule[0].getMolecularWeight() * 1000) }}"></a>{% if not loop.last %} + {% endif %}{% endfor %}</td>
        <td class="family">{{ rxn.getSource().label }}</td>
    </tr>
    <tr class="kinetics {{ rxn.getSource().label|csssafe }}">
        <td></td>
        <td colspan="4">{{ rxn.kinetics.toHTML() }}</td>
    </tr>
    <tr class="chemkin {{ rxn.getSource().label|csssafe }}">
        <td></td>
        <td colspan="4">{{ rxn.toChemkin(species) }}</td>
    </tr>
    <tr class="comment {{ rxn.getSource().label|csssafe }}">
        <td></td>
        <td colspan="4">{{ rxn.kinetics.comment }}</td>
    </tr>
    {% endfor %}

</table>

</body>

</html>
""")
    elif partCoreEdge == 'edge':
        template = environment.from_string(
            """<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
    <title>{{ title }}</title>
    <style type="text/css">
        body {
            font-family: sans-serif;
        }
        a {
            color: #993333;
            text-decoration: none;
        }
        a:visited {
            color: #993333;
        }
        a:hover {
            text-decoration: underline;
        }
        table.speciesList, table.reactionList {
            width: 100%;
            border-collapse: collapse;
        }
        table.speciesList th, table.reactionList th {
            text-align: left;
        }
        tr.reaction td {
            border-top: 1px solid #808080;
        }
        td.reactants {
            text-align: right;
        }
        td.products {
            text-align: left;
        }
        td.reactionArrow {
            text-align: center;
            font-size: 16px;
        }
        td.species img, td.reactants img, td.products img {
            vertical-align: middle;
        }
        tr.comment {
            font-size: small;
        }
        tr.kinetics {
            font-size: small;
        }
        .KineticsData {
            # border: 1px solid gray;
        }
        .KineticsData th {
            width: 15em;
            word-wrap: none;
        }
        .KineticsData td {
            width: 3em;
        }
        
        .chemkin, .KineticsData_repr {
           white-space: pre-wrap;
           font-size: x-small;
           font-family: "Andale Mono", monospace;
        }
        
        .hide_comment .comment{
            display: none !important;
        }
        .hide_kinetics .kinetics{
           display: none !important;
        }
        .hide_chemkin .chemkin{
           display: none !important;
        }
    </style>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.1/jquery.min.js"></script>
    <script type="text/javascript" src="../../../external/jquery.min.js"></script>
    <script type="text/javascript">
    function updateFamily(family) {
        if (family.checked) {
            $("."+family.value).show();
        } else {
            $("."+family.value).hide();
        }
    }
    function updateDetails(type) {
        if (type.checked) {
            $(".reactionList").removeClass("hide_"+type.value);
        } else {
            $(".reactionList").addClass("hide_"+type.value);
        }
    }
    function checkAllFamilies() {
        $("#familySelector").find("[name='family']").each(function() { this.checked = true; updateFamily(this); });
        return false;
    }
    function uncheckAllFamilies() {
        $("#familySelector").find("[name='family']").each(function() { this.checked = false; updateFamily(this); });
        return false;
    }
    function checkAllDetails() {
        $("#familySelector").find("[name='detail']").each(function() { this.checked = true; updateDetails(this); });
        return false;
    }
    function uncheckAllDetails() {
        $("#familySelector").find("[name='detail']").each(function() { this.checked = false; updateDetails(this); });
        return false;
    }
    $(document).ready(function() {
        checkAllFamilies();
        uncheckAllDetails();
    });

    </script>
</head>

<body>

<h1>{{ title }}</h1>

<h2>Species ({{ species|length }})</h2>

<table class="speciesList">
    <tr><th>Index</th><th>Structure</th><th>Label</th><th>Mol. Wt. (g/mol)</th></tr>
    {% for spec in species %}
    <tr class="species">
        <td class="index">
        {{ spec.index }}.</td>
        
        
        
        <td class="structure"><a href={{ spec.molecule[0].getURL() }}><img src="species_edge/{{ spec|replace('#','%23') }}.png" alt="{{ spec }}" title="{{ spec }}"></a></td>
        <td class="label">{{ spec.label }}</td>
        <td>{{ "%.2f"|format(spec.molecule[0].getMolecularWeight() * 1000) }}</td>
    </tr>
    {% if spec.thermo %}
    
    <tr>
     <td>
            <table align="center">
                <tr>
                    <th>H298</th>
                    <th>S298</th>
                    <th>Cp300</th>
                    <th>Cp500</th>
                    <th>Cp1000</th>
                    <th>Cp1500</th>
                </tr>
                <tr>
                    <td>
                    {% if spec.thermo.Tmin.value_si <= 298 %}                    
                    {{ "%.2f"|format(spec.thermo.getEnthalpy(298) / 4184) }}
                    {% endif %} </td>
                    <td>{% if spec.thermo.Tmin.value_si <= 298 %}
                    {{ "%.2f"|format(spec.thermo.getEntropy(298) / 4.184) }}
                    {% endif %}</td>
                    <td>{{ "%.2f"|format(spec.thermo.getHeatCapacity(300) / 4.184) }}</td>
                    <td>{{ "%.2f"|format(spec.thermo.getHeatCapacity(500) / 4.184) }}</td>
                    <td>{{ "%.2f"|format(spec.thermo.getHeatCapacity(1000) / 4.184) }}</td>
                    <td>{{ "%.2f"|format(spec.thermo.getHeatCapacity(1500) / 4.184) }}</td>
                </tr>
            </table>
        </td></tr>
        
        {% endif %}
    {% endfor %}
</table>

<h2>Reactions ({{ reactions|length }})</h2>

<form id='familySelector' action="">
    <h4>Reaction families:</h4>
{% for family in families %}    <input type="checkbox" id="{{ family|csssafe }}" name="family" value="{{ family|csssafe }}" checked="checked" onclick="updateFamily(this);"><label for="{{ family|csssafe }}">{{ family }} ({{ familyCount[family] }} rxn{{ 's' if familyCount[family] != 1 }})</label><br>
{% endfor %}
    <a href="javascript:checkAllFamilies();" onclick="checkAllFamilies()">check all</a> &nbsp; &nbsp; <a href="javascript:uncheckAllFamilies();" onclick="uncheckAllFamilies();">uncheck all</a><br>

    <h4>Reaction Details:</h4>
    <input type="checkbox" id="kinetics" name="detail" value="kinetics" onclick="updateDetails(this);"><label for="kinetics">Kinetics</label><br>
    <input type="checkbox" id="comment" name="detail" value="comment" onclick="updateDetails(this);"><label for="comment">Comments</label><br>
    <input type="checkbox" id="chemkin" name="detail" value="chemkin" onclick="updateDetails(this);"><label for="chemkin">Chemkin strings</label><br>
    <a href="javascript:checkAllDetails();" onclick="checkAllDetails()">check all</a> &nbsp; &nbsp; <a href="javascript:uncheckAllDetails();" onclick="uncheckAllDetails();">uncheck all</a>
</form>

<h4>Reaction List:</h4>

<table class="reactionList hide_comment hide_kinetics hide_chemkin">
    <tr><th>Index</th><th colspan="3" style="text-align: center;">Reaction</th><th>Family</th></tr>
    {% for rxn in reactions %}
    <tr class="reaction {{ rxn.getSource().label|csssafe }}">
        <td class="index"><a href="{{ rxn.getURL() }}" title="Search on RMG website" class="searchlink">{{ rxn.index }}.</a></td>
        <td class="reactants">{% for reactant in rxn.reactants %}<a href="{{ reactant.molecule[0].getURL() }}"><img src="species_edge/{{ reactant|replace('#','%23') }}.png" alt="{{ reactant }}" title="{{ reactant }}, MW = {{ "%.2f g/mol"|format(reactant.molecule[0].getMolecularWeight() * 1000) }}"></a>{% if not loop.last %} + {% endif %}{% endfor %}</td>
        <td class="reactionArrow">{% if rxn.reversible %}&hArr;{% else %}&rarr;{% endif %}</td>
        <td class="products">{% for product in rxn.products %}<a href="{{ product.molecule[0].getURL() }}"><img src="species_edge/{{ product|replace('#','%23') }}.png" alt="{{ product }}" title="{{ product }}, MW = {{ "%.2f g/mol"|format(product.molecule[0].getMolecularWeight() * 1000) }}"></a>{% if not loop.last %} + {% endif %}{% endfor %}</td>
        <td class="family">{{ rxn.getSource().label }}</td>
    </tr>
    <tr class="kinetics {{ rxn.getSource().label|csssafe }}">
        <td></td>
        <td colspan="4">{{ rxn.kinetics.toHTML() }}</td>
    </tr>
    <tr class="chemkin {{ rxn.getSource().label|csssafe }}">
        <td></td>
        <td colspan="4">{{ rxn.toChemkin(species) }}</td>
    </tr>
    <tr class="comment {{ rxn.getSource().label|csssafe }}">
        <td></td>
        <td colspan="4">{{ rxn.kinetics.comment }}</td>
    </tr>
    {% endfor %}

</table>

</body>

</html>
""")

    f = open(path, 'w')
    f.write(
        template.render(title=title,
                        species=species,
                        reactions=reactions,
                        families=families,
                        familyCount=familyCount))
    f.close()
예제 #17
0
    def simulate(self):
        """
        Run all the conditions as a cantera simulation.
        Returns the data as a list of tuples containing: (time, [list of temperature, pressure, and species data]) 
            for each reactor condition
        """
        # Get all the cantera names for the species
        speciesNamesList = [getSpeciesIdentifier(species) for species in self.speciesList]
        inertIndexList = [self.speciesList.index(species) for species in self.speciesList if species.index == -1]
        
        allData = []
        for condition in self.conditions:

            # First translate the molFrac from species objects to species names
            newMolFrac = {}
            for key, value in condition.molFrac.iteritems():
                newkey = getSpeciesIdentifier(key)
                newMolFrac[newkey] = value

            # Set Cantera simulation conditions
            if condition.V0 is None:
                self.model.TPX = condition.T0.value_si, condition.P0.value_si, newMolFrac
            elif condition.P0 is None:
                self.model.TDX = condition.T0.value_si, 1.0/condition.V0.value_si, newMolFrac
            else:
                raise Exception("Cantera conditions in which T0 and P0 or T0 and V0 are not the specified state variables are not yet implemented.")


            # Choose reactor
            if condition.reactorType == 'IdealGasReactor':
                canteraReactor=ct.IdealGasReactor(self.model)
            elif condition.reactorType == 'IdealGasConstPressureReactor':
                canteraReactor=ct.IdealGasConstPressureReactor(contents=self.model)
            elif condition.reactorType == 'IdealGasConstPressureTemperatureReactor':
                canteraReactor=ct.IdealGasConstPressureReactor(contents=self.model, energy='off')
            else:
                raise Exception('Other types of reactor conditions are currently not supported')
            
            # Run this individual condition as a simulation
            canteraSimulation=ct.ReactorNet([canteraReactor])
            
            numCtReactions = len(self.model.reactions())
            if self.sensitiveSpecies:
                if ct.__version__ == '2.2.1':
                    print 'Warning: Cantera version 2.2.1 may not support sensitivity analysis unless SUNDIALS was used during compilation.'
                    print 'Warning: Upgrade to newer of Cantera in anaconda using the command "conda update -c rmg cantera"'
                # Add all the reactions as part of the analysis
                for i in range(numCtReactions):
                    canteraReactor.add_sensitivity_reaction(i)
                # Set the tolerances for the sensitivity coefficients
                canteraSimulation.rtol_sensitivity = 1e-4
                canteraSimulation.atol_sensitivity = 1e-6
                
            # Initialize the variables to be saved
            times=[]
            temperature=[]
            pressure=[]
            speciesData=[]
            sensitivityData = []
            
            # Begin integration
            time = 0.0
            # Run the simulation over 100 time points
            while canteraSimulation.time<condition.reactionTime.value_si:

                # Advance the state of the reactor network in time from the current time to time t [s], taking as many integrator timesteps as necessary.
                canteraSimulation.step(condition.reactionTime.value_si)
                times.append(canteraSimulation.time)
                temperature.append(canteraReactor.T)
                pressure.append(canteraReactor.thermo.P)
                speciesData.append(canteraReactor.thermo[speciesNamesList].X)
                
                
                if self.sensitiveSpecies:
                    # Cantera returns mass-based sensitivities rather than molar concentration or mole fraction based sensitivities.
                    # The equation for converting between them is:
                    # 
                    # d ln xi = d ln wi - sum_(species i) (dln wi) (xi)
                    # 
                    # where xi is the mole fraction of species i and wi is the mass fraction of species i
                    
                    massFracSensitivityArray = canteraSimulation.sensitivities()
                    if condition.reactorType =='IdealGasReactor':
                        # Row 0: mass, Row 1: volume, Row 2: internal energy or temperature, Row 3+: mass fractions of species
                        massFracSensitivityArray = massFracSensitivityArray[3:,:]
                    elif condition.reactorType == 'IdealGasConstPressureReactor' or condition.reactorType == 'IdealGasConstPressureTemperatureReactor':
                        # Row 0: mass, Row 1: enthalpy or temperature, Row 2+: mass fractions of the species
                        massFracSensitivityArray = massFracSensitivityArray[2:,:]
                    else:
                        raise Exception('Other types of reactor conditions are currently not supported')
                    
                    for i in range(len(massFracSensitivityArray)):
                        massFracSensitivityArray[i] *= speciesData[-1][i]
                        
                    sensitivityArray= np.zeros(len(self.sensitiveSpecies)*len(self.model.reactions()))
                    for index, species in enumerate(self.sensitiveSpecies):
                        for j in range(numCtReactions):
                            sensitivityArray[numCtReactions*index+j] = canteraSimulation.sensitivity(species.toChemkin(),j)

                            for i in range(len(massFracSensitivityArray)):
                                if i not in inertIndexList:
                                    # massFracSensitivity for inerts are returned as nan in Cantera, so we must not include them here
                                    sensitivityArray[numCtReactions*index+j] -= massFracSensitivityArray[i][j]
                    sensitivityData.append(sensitivityArray)
                
            # Convert speciesData and sensitivityData to a numpy array
            speciesData=np.array(speciesData)
            sensitivityData = np.array(sensitivityData)

            # Resave data into generic data objects
            time = GenericData(label = 'Time', 
                               data = times,
                               units = 's')
            temperature = GenericData(label='Temperature',
                                      data = temperature,
                                      units = 'K')
            pressure = GenericData(label='Pressure',
                                      data = pressure,
                                      units = 'Pa')
            conditionData = []
            conditionData.append(temperature)
            conditionData.append(pressure)
            
            for index, species in enumerate(self.speciesList):
                # Create generic data object that saves the species object into the species object.  To allow easier manipulate later.
                speciesGenericData = GenericData(label=speciesNamesList[index],
                                          species = species,
                                          data = speciesData[:,index],
                                          index = species.index
                                          )
                conditionData.append(speciesGenericData)
            
            reactionSensitivityData = []
            for index, species in enumerate(self.sensitiveSpecies):
                for j in range(numCtReactions):
                    reactionSensitivityGenericData = GenericData(label = 'dln[{0}]/dln[k{1}]: {2}'.format(species.toChemkin(),j+1, self.model.reactions()[j]),
                                  species = species,
                                  reaction = self.model.reactions()[j],
                                  data = sensitivityData[:,numCtReactions*index+j],
                                  index = j+1,
                                  )
                    reactionSensitivityData.append(reactionSensitivityGenericData)
            
            allData.append((time,conditionData,reactionSensitivityData))
            
        return allData
예제 #18
0
    chemkinPath = args.chemkinPath[0]

    #Save output in same directory as input
    outputDirectory = os.path.dirname(os.path.abspath(chemkinPath))

    # Initialize (and clear!) the output files for the job
    outputFile = os.path.join(outputDirectory, 'evaluated_NASA_polynomial.py')
    with open(outputFile, 'w') as f:
        pass

    #Load the checmkin file
    speciesList, reactionList = loadChemkinFile(chemkinPath)

    # Make full species identifier the species labels
    for species in speciesList:
        species.label = getSpeciesIdentifier(species)
        species.index = -1

    # Evaluate the NASA polynomials for thermo properties of each species at the specified T's and save in tabular format
    # to output file
    for i in range(len(speciesList)): 
        species = speciesList[i]
        if species.thermo:

            f = open(outputFile, 'a')

            f.write('# Thermodynamics for {0}:\n'.format(species.label))
            H298 = species.getThermoData().getEnthalpy(298) / 4184.
            S298 = species.getThermoData().getEntropy(298) / 4.184
            f.write('#   Enthalpy of formation (298 K)   = {0:9.3f} kcal/mol\n'.format(H298))
            f.write('#   Entropy of formation (298 K)    = {0:9.3f} cal/(mol*K)\n'.format(S298))
예제 #19
0
 def update_all_labels(self):
     """Update species and reaction labels to match Chemkin labels"""
     for reaction in self.reactions:
         reaction.label = reaction.toChemkin(kinetics=False)
     for species in self.species:
         species.label = getSpeciesIdentifier(species)
     help='The path of the chemkin file')    
 parser.add_argument('dictionaryPath', metavar='DICTIONARY', type=str, nargs=1,
     help='The path of the RMG dictionary file')     
 parser.add_argument('name', metavar='NAME', type=str, nargs=1,
     help='Name of the chemkin library to be saved') 
 
 args = parser.parse_args()
 chemkinPath = args.chemkinPath[0]
 dictionaryPath = args.dictionaryPath[0]
 name = args.name[0]
     
 speciesList, reactionList = loadChemkinFile(chemkinPath, dictionaryPath)
 
 # Make full species identifier the species labels
 for species in speciesList:
     species.label = getSpeciesIdentifier(species)
     species.index = -1
 # load thermo library entries
 thermoLibrary = ThermoLibrary(name=name)
 for i in range(len(speciesList)): 
     species = speciesList[i]
     if species.thermo:
         thermoLibrary.loadEntry(index = i + 1,
                                 label = species.label,
                                 molecule = species.molecule[0].toAdjacencyList(),
                                 thermo = species.thermo,
                                 shortDesc = species.thermo.comment
        )                
     else:
         logging.warning('Species {0} did not contain any thermo data and was omitted from the thermo library.'.format(str(species)))
                     
예제 #21
0
파일: output.py 프로젝트: vrlambert/RMG-Py
def saveDiffHTML(path, commonSpeciesList, speciesList1, speciesList2, commonReactions, uniqueReactions1, uniqueReactions2):
    """
    This function outputs the species and reactions on an HTML page
    for the comparison of two RMG models.
    """
    from model import PDepReaction
    from rmgpy.kinetics import Arrhenius, MultiArrhenius, MultiPDepArrhenius

    from rmgpy.molecule.draw import MoleculeDrawer
    try:
        import jinja2
    except ImportError:
        logging.warning("jinja package not found; HTML output will not be saved.")
        return

    path = os.path.abspath(path)
    dirname = os.path.dirname(path)

    # Prepare parameters to pass to jinja template
    title = 'RMG Model Comparison'

    speciesList = [spec1 for spec1, spec2 in commonSpeciesList] + [spec2 for spec1, spec2 in commonSpeciesList] + speciesList1 + speciesList2
    re_index = re.compile(r'\((\d+)\)$')

        
    if not os.path.isdir(os.path.join(dirname,'species1')):
        os.makedirs(os.path.join(dirname,'species1'))    
    
    if not os.path.isdir(os.path.join(dirname,'species2')):
        os.makedirs(os.path.join(dirname,'species2'))

    for spec1, spec2 in commonSpeciesList:
        # if the species dictionary came from an RMG-Java job, make them prettier
        # We use the presence of a trailing index on the label to discern this
        # (A single open parenthesis is not enough (e.g. when using SMILES strings as labels!)
        match1 = re_index.search(spec1.label)
        if match1:
            spec1.index = int(match1.group(0)[1:-1])
            spec1.label = spec1.label[0:match1.start()]

        match2 = re_index.search(spec2.label)            
        if match2:
            spec2.index = int(match2.group(0)[1:-1])
            spec2.label = spec2.label[0:match2.start()]            
        
        # Draw molecules if necessary
        fstr = os.path.join(dirname, 'species1', '{0}.png'.format(spec1))
        if not os.path.exists(fstr):
            try:
                MoleculeDrawer().draw(spec1.molecule[0], 'png', fstr)
            except IndexError:
                raise OutputError('{0} species could not be drawn because it did not contain a molecular structure. Please recheck your files.'.format(getSpeciesIdentifier(spec1)))

            
        fstr = os.path.join(dirname, 'species2', '{0}.png'.format(spec2))
        if not os.path.exists(fstr):
            try:
                MoleculeDrawer().draw(spec2.molecule[0], 'png', fstr)
            except IndexError:
                raise OutputError('{0} species could not be drawn because it did not contain a molecular structure. Please recheck your files.'.format(getSpeciesIdentifier(spec2)))
    
                
    for spec in speciesList1:
        match = re_index.search(spec.label)
        if match:
            spec.index = int(match.group(0)[1:-1])
            spec.label = spec.label[0:match.start()]
        # Draw molecules if necessary
        fstr = os.path.join(dirname, 'species1', '{0}.png'.format(spec))
        if not os.path.exists(fstr):
            try:
                MoleculeDrawer().draw(spec.molecule[0], 'png', fstr)
            except IndexError:
                raise OutputError('{0} species could not be drawn because it did not contain a molecular structure. Please recheck your files.'.format(getSpeciesIdentifier(spec)))
    
    for spec in speciesList2:
        match = re_index.search(spec.label)
        if match:
            spec.index = int(match.group(0)[1:-1])
            spec.label = spec.label[0:match.start()]
        # Draw molecules if necessary
        fstr = os.path.join(dirname, 'species2', '{0}.png'.format(spec))
        if not os.path.exists(fstr):
            try:
                MoleculeDrawer().draw(spec.molecule[0], 'png', fstr)
            except IndexError:
                raise OutputError('{0} species could not be drawn because it did not contain a molecular structure. Please recheck your files.'.format(getSpeciesIdentifier(spec)))
    


    familyCount1 = {}
    familyCount2 = {}
    for rxn1, rxn2 in commonReactions:
        if isinstance(rxn2.kinetics, (MultiArrhenius,MultiPDepArrhenius)):
            rxn2.duplicate = True   
        if isinstance(rxn1, PDepReaction):
            family = "PDepNetwork"
        else:
            family = rxn1.getSource().label
        if family in familyCount1:
            familyCount1[family] += 1
            familyCount2[family] += 1
        else:
            familyCount1[family] = 1
            familyCount2[family] = 1

    for rxn in uniqueReactions1:
        if isinstance(rxn, PDepReaction):
            family = "PDepNetwork"
        else:
            family = rxn.getSource().label
        if family in familyCount1:
            familyCount1[family] += 1
        else:
            familyCount1[family] = 1

    for rxn in uniqueReactions2:
        if isinstance(rxn, PDepReaction):
            family = "PDepNetwork"
        else:
            family = rxn.getSource().label
        if family in familyCount2:
            familyCount2[family] += 1
        else:
            familyCount2[family] = 1

    families1 = familyCount1.keys()
    families2 = familyCount2.keys()
    families1.sort()
    families2.sort()



    ## jinja2 filters etc.
    to_remove_from_css_names = re.compile('[/.\-+,]')
    def csssafe(input):
        "Replace unsafe CSS class name characters with an underscore."
        return to_remove_from_css_names.sub('_',input)

    environment = jinja2.Environment()
    environment.filters['csssafe'] = csssafe

# Make HTML file
    template = environment.from_string(
"""<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
    <title>{{ title }}</title>
    <style type="text/css">
        body {
            font-family: sans-serif;
        }
        a {
            color: #993333;
            text-decoration: none;
        }
        a:visited {
            color: #993333;
        }
        a:hover {
            text-decoration: underline;
        }
        table.speciesList, table.reactionList {
            width: 100%;
            border-collapse: collapse;
        }
        table.speciesList th, table.reactionList th {
            text-align: left;
        }
        tr.reaction td {
            border-top: 1px solid #808080;
        }
        td.reactants {
            text-align: right;
        }
        td.products {
            text-align: left;
        }
        td.reactionArrow {
            text-align: center;
            font-size: 16px;
        }
        td.species img, td.reactants img, td.products img {
            vertical-align: middle;
        }
        tr.comment {
            font-size: small;
        }
        tr.kinetics {
            font-size: small;
        }
        .KineticsData {
            # border: 1px solid gray;
        }
        .KineticsData th {
            width: 15em;
            word-wrap: none;
        }
        .KineticsData td {
            width: 3em;
        }

        .chemkin, .KineticsData_repr {
           white-space: pre-wrap;
           font-size: x-small;
           font-family: "Andale Mono", monospace;
        }

        .hide_comment .comment{
            display: none !important;
        }
        .hide_kinetics .kinetics{
           display: none !important;
        }
        .hide_chemkin .chemkin{
           display: none !important;
        }
    </style>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.1/jquery.min.js"></script>
    <script type="text/javascript" src="../../../external/jquery.min.js"></script>
    <script type="text/javascript">
    function updateFamily(family) {
        if (family.checked) {
            $("."+family.value).show();
        } else {
            $("."+family.value).hide();
        }
    }
    function updateDetails(type) {
        if (type.checked) {
            $(".reactionList").removeClass("hide_"+type.value);
        } else {
            $(".reactionList").addClass("hide_"+type.value);
        }
    }
    function checkAllFamilies() {
        $("#familySelector").find("[name='family']").each(function() { this.checked = true; updateFamily(this); });
        return false;
    }
    function uncheckAllFamilies() {
        $("#familySelector").find("[name='family']").each(function() { this.checked = false; updateFamily(this); });
        return false;
    }
    function checkAllDetails() {
        $("#familySelector").find("[name='detail']").each(function() { this.checked = true; updateDetails(this); });
        return false;
    }
    function uncheckAllDetails() {
        $("#familySelector").find("[name='detail']").each(function() { this.checked = false; updateDetails(this); });
        return false;
    }
    $(document).ready(function() {
        checkAllFamilies();
        uncheckAllDetails();
    });

    </script>
</head>

<body>

<h1>{{ title }}</h1>

<h2 align="center">Common Species ({{ commonSpecies|length }})</h2>

<table width="100%">
    {% for spec1, spec2 in commonSpecies %}
    <tr>
        <td width="100%" colspan="4">
            <table align="center">
                <tr class="species">
                    <td>{{ spec1.label }}</td>
                    <td class="structure" align="center"><a href="{{spec1.molecule[0].getURL()}}"><img src="species1/{{ spec1|replace('#','%23') }}.png" alt="{{ spec1 }}" title="{{ spec1 }}"></a></td>
                    <td>{{ "%.2f"|format(spec1.molecule[0].getMolecularWeight() * 1000) }}</td>
                </tr>
            </table>
        </td>
    </tr>
    {% if spec1.thermo and spec2.thermo %}
    {% if spec1.thermo.isIdenticalTo(spec2.thermo) %}
    <tr width=100%>
         <td colspan="4" valign="top" width=50%><div align="center"><font color="blue">IDENTICAL THERMO WAS FOUND FOR THIS SPECIES.</font></div>
    </tr>
    {% elif spec1.thermo.isSimilarTo(spec2.thermo) %}
    <tr width=100%>
         <td colspan="4" valign="top" width=50%><div align="center"><font color="green">SIMILAR THERMO WAS FOUND FOR THIS SPECIES.</font></div>
    </tr>
    {% else %}
     <tr width=100%>
         <td colspan="4" valign="top" width=50%><div align="center"><font color="red">DIFFERENT THERMO WAS FOUND FOR THIS SPECIES.</font></div>
    </tr>
    {% endif%}
    <tr>
        <td width="10%">{{ spec1.index }}. </td>
        <td width="40%">
            <table width="100%">
                <tr>
                    <th>H298</th>
                    <th>S298</th>
                    <th>Cp300</th>
                    <th>Cp500</th>
                    <th>Cp1000</th>
                    <th>Cp1500</th>
                </tr>
                <tr>
                    <td>{% if spec1.thermo.Tmin.value_si <= 298 %}
                    {{ "%.2f"|format(spec1.thermo.getEnthalpy(298) / 4184) }}
                    {% endif %}</td>
                    <td>
                    {% if spec1.thermo.Tmin.value_si <= 298 %}
                    {{ "%.2f"|format(spec1.thermo.getEntropy(298) / 4.184) }}
                    {% endif %}</td>
                    <td>{{ "%.2f"|format(spec1.thermo.getHeatCapacity(300) / 4.184) }}</td>
                    <td>{{ "%.2f"|format(spec1.thermo.getHeatCapacity(500) / 4.184) }}</td>
                    <td>{{ "%.2f"|format(spec1.thermo.getHeatCapacity(1000) / 4.184) }}</td>
                    <td>{{ "%.2f"|format(spec1.thermo.getHeatCapacity(1500) / 4.184) }}</td>
                </tr>
            </table>
        </td>
        <td width="10%">{{ spec2.index }}.</td>
        <td width="40%">
            <table width="100%">
                <tr>
                    <th>H298</th>
                    <th>S298</th>
                    <th>Cp300</th>
                    <th>Cp500</th>
                    <th>Cp1000</th>
                    <th>Cp1500</th>
                </tr>
                <tr>
                    <td>{% if spec2.thermo.Tmin.value_si <= 298 %}
                    {{ "%.2f"|format(spec2.thermo.getEnthalpy(298) / 4184) }}
                    {% endif %}</td>
                    <td>{% if spec2.thermo.Tmin.value_si <= 298 %}
                    {{ "%.2f"|format(spec2.thermo.getEntropy(298) / 4.184) }}
                    {% endif %}</td>
                    <td>{{ "%.2f"|format(spec2.thermo.getHeatCapacity(300) / 4.184) }}</td>
                    <td>{{ "%.2f"|format(spec2.thermo.getHeatCapacity(500) / 4.184) }}</td>
                    <td>{{ "%.2f"|format(spec2.thermo.getHeatCapacity(1000) / 4.184) }}</td>
                    <td>{{ "%.2f"|format(spec2.thermo.getHeatCapacity(1500) / 4.184) }}</td>
                </tr>
            </table>
        </td>
    </tr>
    {% endif %}
    <tr>
        <td width="100%" colspan="4"><hr/></td>
    </tr>
    {% endfor %}
</table>

<table width=100%>
<tr colspan="2">
<td width=50% valign="top">

<h2>Model 1: Unique Species ({{ speciesList1|length }})</h2>
<table class="speciesList">
    <tr><th>Index</th><th>Structure</th><th>Label</th><th>Mol. Wt. (g/mol)</th></tr>
    {% for spec in speciesList1 %}
    <tr class="species">
        <td class="index">
        {{ spec.index }}.</td>
        <td class="structure"><a href="{{ spec.molecule[0].getURL() }}"><img src="species1/{{ spec|replace('#','%23') }}.png" alt="{{ spec }}" title="{{ spec }}"></a></td>
        <td class="label">{{ spec.label }}</td>
        <td>{{ "%.2f"|format(spec.molecule[0].getMolecularWeight() * 1000) }}</td>
    </tr>
    {% endfor %}
</table>
</td>
<td width=50% valign="top">
<h2>Model 2: Unique Species ({{ speciesList2|length }})</h2>
<table class="speciesList">
    <tr><th>Index</th><th>Structure</th><th>Label</th><th>Mol. Wt. (g/mol)</th></tr>
    {% for spec in speciesList2 %}
    <tr class="species">
        <td class="index">
        {{ spec.index }}.</td>
        <td class="structure"><a href="{{ spec.molecule[0].getURL() }}"><img src="species2/{{ spec|replace('#','%23') }}.png" alt="{{ spec }}" title="{{ spec }}"></a></td>
        <td class="label">{{ spec.label }}</td>
        <td>{{ "%.2f"|format(spec.molecule[0].getMolecularWeight() * 1000) }}</td>
    </tr>
    {% endfor %}
</table>
</td></tr>

<tr colspan="2">
<td width=50% valign="top">
<h2>Model 1 Reactions ({{ commonReactions|length + uniqueReactions1|length}})</h2>

<form id='familySelector' action="">
    <h4>Reaction families:</h4>
{% for family in families1 %}    <input type="checkbox" id="{{ family|csssafe }}" name="family" value="{{ family|csssafe }}" checked="checked" onclick="updateFamily(this);"><label for="{{ family|csssafe }}">{{ family }} ({{ familyCount1[family] }} rxn{{ 's' if familyCount1[family] != 1 }})</label><br>
{% endfor %}
    <a href="javascript:checkAllFamilies();" onclick="checkAllFamilies()">check all</a> &nbsp; &nbsp; <a href="javascript:uncheckAllFamilies();" onclick="uncheckAllFamilies();">uncheck all</a><br>

    <h4>Reaction Details:</h4>
    <input type="checkbox" id="kinetics" name="detail" value="kinetics" onclick="updateDetails(this);"><label for="kinetics">Kinetics</label><br>
    <input type="checkbox" id="comment" name="detail" value="comment" onclick="updateDetails(this);"><label for="comment">Comments</label><br>
    <input type="checkbox" id="chemkin" name="detail" value="chemkin" onclick="updateDetails(this);"><label for="chemkin">Chemkin strings</label><br>
    <a href="javascript:checkAllDetails();" onclick="checkAllDetails()">check all</a> &nbsp; &nbsp; <a href="javascript:uncheckAllDetails();" onclick="uncheckAllDetails();">uncheck all</a>
</form>
</td>

<td width=50% valign="top">
<h2>Model 2 Reactions ({{ commonReactions|length +uniqueReactions2|length}})</h2>

<form id='familySelector' action="">
    <h4>Reaction families:</h4>
{% for family in families2 %}    <input type="checkbox" id="{{ family|csssafe }}" name="family" value="{{ family|csssafe }}" checked="checked" onclick="updateFamily(this);"><label for="{{ family|csssafe }}">{{ family }} ({{ familyCount2[family] }} rxn{{ 's' if familyCount2[family] != 1 }})</label><br>
{% endfor %}
    <a href="javascript:checkAllFamilies();" onclick="checkAllFamilies()">check all</a> &nbsp; &nbsp; <a href="javascript:uncheckAllFamilies();" onclick="uncheckAllFamilies();">uncheck all</a><br>

    <h4>Reaction Details:</h4>
    <input type="checkbox" id="kinetics" name="detail" value="kinetics" onclick="updateDetails(this);"><label for="kinetics">Kinetics</label><br>
    <input type="checkbox" id="comment" name="detail" value="comment" onclick="updateDetails(this);"><label for="comment">Comments</label><br>
    <input type="checkbox" id="chemkin" name="detail" value="chemkin" onclick="updateDetails(this);"><label for="chemkin">Chemkin strings</label><br>
    <a href="javascript:checkAllDetails();" onclick="checkAllDetails()">check all</a> &nbsp; &nbsp; <a href="javascript:uncheckAllDetails();" onclick="uncheckAllDetails();">uncheck all</a>
</form>
</td>
</tr>

</table>


<table width=100%>
<tr><td width=100% align="center">
<h2>Common Reactions ({{ commonReactions|length}})</h2></td></tr>


<tr colspan="1"><td width=100%>

<table class="reactionList hide_comment hide_kinetics hide_chemkin" width=100% cellpadding="10">
    <tr colspan="4" width=100%><th>Index.</th><th>Family</th><th>Index.</th><th>Family</th></tr>

    {% for rxn1, rxn2 in commonReactions %}

<tr>
<td width=100% colspan="4"><hr>
<table align="center">
<tr>
    <td class="reactants" align="right">{% for reactant in rxn1.reactants %}<a href="{{reactant.molecule[0].getURL() }}"><img src="species1/{{ reactant|replace('#','%23') }}.png" alt="{{ reactant }}" title="{{ reactant }}, MW = {{ "%.2f"|format(reactant.molecule[0].getMolecularWeight() * 1000) }}"></a>{% if not loop.last %} + {% endif %}{% endfor %}</td>
    <td class="reactionArrow" align="center">{% if rxn1.reversible %}&hArr;{% else %}&rarr;{% endif %}</td>
    <td class="products" align="left">{% for product in rxn1.products %}<a href="{{product.molecule[0].getURL()}}"><img src="species1/{{ product|replace('#','%23') }}.png" alt="{{ product }}" title="{{ product }}, MW = {{ "%.2f"|format(product.molecule[0].getMolecularWeight() * 1000) }}"></a>{% if not loop.last %} + {% endif %}{% endfor %}</td>
</tr>
</table>
</td>
</tr>


{% if rxn1.kinetics.isIdenticalTo(rxn2.kinetics) %}

 <tr width=100%>
     <td colspan="4" valign="top" width=50%><div align="center"><font color="blue">IDENTICAL KINETICS WERE FOUND FOR THIS REACTION.</font></div>

</tr>
{% elif rxn1.kinetics.isSimilarTo(rxn2.kinetics) %}

 <tr width=100%>
     <td colspan="4" valign="top" width=50%><div align="center"><font color="green">SIMILAR KINETICS WERE FOUND FOR THIS REACTION.</font></div>

</tr>

{% else %}
     <tr width=100%>
         <td colspan="4" valign="top" width=50%><div align="center"><font color="red">DIFFERENT KINETICS WERE FOUND FOR THIS REACTION.</font></div>
    </tr>
{% endif%}


<tr width=100%>
     <td class="index" width=10%><a href="{{ rxn1.getURL() }}" title="Search on RMG website" class="searchlink">{{ rxn1.index }}.</a></td>
     <td class="family" width=40%>{{ rxn1.getSource().label }}</td>

     <td class="index" width=10%><a href="{{ rxn2.getURL() }}" title="Search on RMG website" class="searchlink">{{ rxn2.index }}.</a></td>
     <td class="family" width=40%>{{ rxn2.getSource().label }}</td>
 </tr>

<tr width=100%>{% if not rxn1.isIsomorphic(rxn2, eitherDirection=False) %} 
<td colspan="2" width=50%></td>
<td colspan="2" width=50%>* Reaction was found in reverse 


{% if not rxn2.duplicate %}
<P><b>Fitted Reverse Kinetics:</b>
{{rxn2.generateReverseRateCoefficient().toHTML() }}

{% endif %}

<P><b>Original Kinetics:</b>
{% endif %}</td>
</tr>

<tr width=100%>
     <td colspan="2" valign="top" width=50%>
     
     {{ rxn1.kinetics.toHTML() }}</td>
     <td colspan="2" valign="top" width=50%>
     {{ rxn2.kinetics.toHTML() }}</td>
</tr>

<tr width=100%>
    <td colspan="2" valign="top" width=50%><font size="1pt" face="courier">{{ rxn1.toChemkin(speciesList) }}</font></td>
    <td colspan="2" valign="top" width=50%><font size="1pt" face="courier">{{ rxn2.toChemkin(speciesList) }}</font></td>
</tr>

<tr width=100%>
    <td colspan="2" valign="top" width=50%><font size="1pt">{{ rxn1.kinetics.comment }}</font></td>
    <td colspan="2" valign="top" width=50%><font size="1pt">{{ rxn2.kinetics.comment }}</font></td>
</tr>
{% endfor %}

</table>
</td></tr></table>

<table>
<tr>
<td width=50% valign="top">
<h2>Model 1: Unique Reactions ({{ uniqueReactions1|length}})</h2>

<table class="reactionList hide_comment hide_kinetics hide_chemkin">
    <tr><th>Index</th><th colspan="3" style="text-align: center;">Reaction</th><th>Family</th></tr>
    {% for rxn in uniqueReactions1 %}
    <tr class="reaction {{ rxn.getSource().label|csssafe }}">
        <td class="index"><a href="{{ rxn.getURL() }}" title="Search on RMG website" class="searchlink">{{ rxn.index }}.</a></td>
        <td class="reactants">{% for reactant in rxn.reactants %}<a href="{{ reactant.molecule[0].getURL() }}"><img src="species1/{{ reactant|replace('#','%23') }}.png" alt="{{ reactant }}" title="{{ reactant }}, MW = {{ "%.2f"|format(reactant.molecule[0].getMolecularWeight() * 1000) }}"></a>{% if not loop.last %} + {% endif %}{% endfor %}</td>
        <td class="reactionArrow">{% if rxn.reversible %}&hArr;{% else %}&rarr;{% endif %}</td>
        <td class="products">{% for product in rxn.products %}<a href="{{ product.molecule[0].getURL() }}"><img src="species1/{{ product|replace('#','%23') }}.png" alt="{{ product }}" title="{{ product }}, MW = {{ "%.2f"|format(product.molecule[0].getMolecularWeight() * 1000) }}"></a>{% if not loop.last %} + {% endif %}{% endfor %}</td>
        <td class="family">{{ rxn.getSource().label }}</td>
    </tr>
    <tr class="kinetics {{ rxn.getSource().label|csssafe }}">
        <td></td>
        <td colspan="4">{{ rxn.kinetics.toHTML() }}</td>
    </tr>
    <tr class="chemkin {{ rxn.getSource().label|csssafe }}">
        <td></td>
        <td colspan="4">{{ rxn.toChemkin(species) }}</td>
    </tr>
    <tr class="comment {{ rxn.getSource().label|csssafe }}">
        <td></td>
        <td colspan="4">{{ rxn.kinetics.comment }}</td>
    </tr>
    {% endfor %}
    </table>

</td>

<td width=50% valign="top">
<h2>Model 2: Unique Reactions ({{ uniqueReactions2|length}})</h2>

<table class="reactionList hide_comment hide_kinetics hide_chemkin">
    <tr><th>Index</th><th colspan="3" style="text-align: center;">Reaction</th><th>Family</th></tr>
    {% for rxn in uniqueReactions2 %}
    <tr class="reaction {{ rxn.getSource().label|csssafe }}">
        <td class="index"><a href="{{ rxn.getURL() }}" title="Search on RMG website" class="searchlink">{{ rxn.index }}.</a></td>
        <td class="reactants">{% for reactant in rxn.reactants %}<a href="{{ reactant.molecule[0].getURL() }}"><img src="species2/{{ reactant|replace('#','%23') }}.png" alt="{{ reactant }}" title="{{ reactant }}, MW = {{ "%.2f"|format(reactant.molecule[0].getMolecularWeight() * 1000) }}"></a>{% if not loop.last %} + {% endif %}{% endfor %}</td>
        <td class="reactionArrow">{% if rxn.reversible %}&hArr;{% else %}&rarr;{% endif %}</td>
        <td class="products">{% for product in rxn.products %}<a href="{{ product.molecule[0].getURL() }}"><img src="species2/{{ product|replace('#','%23') }}.png" alt="{{ product }}" title="{{ product }}, MW = {{ "%.2f"|format(product.molecule[0].getMolecularWeight() * 1000) }}"></a>{% if not loop.last %} + {% endif %}{% endfor %}</td>
        <td class="family">{{ rxn.getSource().label }}</td>
    </tr>
    <tr class="kinetics {{ rxn.getSource().label|csssafe }}">
        <td></td>
        <td colspan="4">{{ rxn.kinetics.toHTML() }}</td>
    </tr>
    <tr class="chemkin {{ rxn.getSource().label|csssafe }}">
        <td></td>
        <td colspan="4">{{ rxn.toChemkin(species) }}</td>
    </tr>
    <tr class="comment {{ rxn.getSource().label|csssafe }}">
        <td></td>
        <td colspan="4">{{ rxn.kinetics.comment }}</td>
    </tr>
    {% endfor %}
    </table>

</td>

</table>



</body>

</html>
""")
    f = open(path, 'w')
    f.write(template.render(title=title, commonSpecies=commonSpeciesList, speciesList1=speciesList1, speciesList2 = speciesList2, commonReactions=commonReactions, uniqueReactions1=uniqueReactions1, uniqueReactions2=uniqueReactions2, families1=families1, families2=families2, familyCount1=familyCount1,familyCount2=familyCount2, speciesList=speciesList))
    f.close()
예제 #22
0
def generateCanteraConditions(reactorType,
                              reactionTime,
                              molFracList,
                              Tlist=None,
                              Plist=None,
                              Vlist=None):
    """
        Creates a list of cantera conditions from from the arguments provided. 
        
        ======================= ====================================================
        Argument                Description
        ======================= ====================================================
        `reactorType`           A string of the cantera reactor type. List of supported types below:
            IdealGasReactor: A constant volume, zero-dimensional reactor for ideal gas mixtures
            IdealGasConstPressureReactor: A homogeneous, constant pressure, zero-dimensional reactor for ideal gas mixtures

        `reactionTime`          A tuple object giving the (reaction time, units)
        `molFracList`           A list of molfrac dictionaries with either string or species object keys 
                               and mole fraction values
        To specify the system for an ideal gas, you must define 2 of the following 3 parameters:
        `T0`                    A tuple giving the ([list of initial temperatures], units) 
        'P0'                    A tuple giving the ([list of initial pressures], units) 
        'V0'                    A tuple giving the ([list of initial volumes], units) 
    
        
        This saves all the reaction conditions into the Cantera class.
        """
    # First translate the molFracList from species objects to species names if needed
    newMolFracList = []
    for molFrac in molFracList:
        newMolFrac = {}
        for key, value in molFrac.iteritems():
            if isinstance(key, Species):
                newkey = getSpeciesIdentifier(key)
            else:
                newkey = key
            newMolFrac[newkey] = value
        newMolFracList.append(newMolFrac)

    molFracList = newMolFracList

    # Create individual ScalarQuantity objects for Tlist, Plist, Vlist
    if Tlist:
        Tlist = Quantity(
            Tlist)  # Be able to create a Quantity object from it first
        Tlist = [(Tlist.value[i], Tlist.units)
                 for i in range(len(Tlist.value))]
    if Plist:
        Plist = Quantity(Plist)
        Plist = [(Plist.value[i], Plist.units)
                 for i in range(len(Plist.value))]
    if Vlist:
        Vlist = Quantity(Vlist)
        Vlist = [(Vlist.value[i], Vlist.units)
                 for i in range(len(Vlist.value))]

    conditions = []

    if Tlist is None:
        for molFrac in molFracList:
            for P in Plist:
                for V in Vlist:
                    conditions.append(
                        CanteraCondition(reactorType,
                                         reactionTime,
                                         molFrac,
                                         P0=P,
                                         V0=V))

    elif Plist is None:
        for molFrac in molFracList:
            for T in Tlist:
                for V in Vlist:
                    conditions.append(
                        CanteraCondition(reactorType,
                                         reactionTime,
                                         molFrac,
                                         T0=T,
                                         V0=V))

    elif Vlist is None:
        for molFrac in molFracList:
            for T in Tlist:
                for P in Plist:
                    conditions.append(
                        CanteraCondition(reactorType,
                                         reactionTime,
                                         molFrac,
                                         T0=T,
                                         P0=P))

    else:
        raise Exception(
            "Cantera conditions must leave one of T0, P0, and V0 state variables unspecified"
        )
    return conditions
예제 #23
0
def generateCanteraConditions(reactorType, reactionTime, molFracList, Tlist=None, Plist=None, Vlist=None):
        """
        Creates a list of cantera conditions from from the arguments provided. 
        
        ======================= ====================================================
        Argument                Description
        ======================= ====================================================
        `reactorType`           A string of the cantera reactor type. List of supported types below:
            IdealGasReactor: A constant volume, zero-dimensional reactor for ideal gas mixtures
            IdealGasConstPressureReactor: A homogeneous, constant pressure, zero-dimensional reactor for ideal gas mixtures

        `reactionTime`          A tuple object giving the (reaction time, units)
        `molFracList`           A list of molfrac dictionaries with either string or species object keys 
                               and mole fraction values
        To specify the system for an ideal gas, you must define 2 of the following 3 parameters:
        `T0`                    A tuple giving the ([list of initial temperatures], units) 
        'P0'                    A tuple giving the ([list of initial pressures], units) 
        'V0'                    A tuple giving the ([list of initial volumes], units) 
    
        
        This saves all the reaction conditions into the Cantera class.
        """
        # First translate the molFracList from species objects to species names if needed
        newMolFracList = []
        for molFrac in molFracList:
            newMolFrac = {}
            for key, value in molFrac.iteritems():
                if isinstance(key, Species):
                    newkey = getSpeciesIdentifier(key)
                else:
                    newkey = key
                newMolFrac[newkey] = value
            newMolFracList.append(newMolFrac)
            
        molFracList = newMolFracList
        
        # Create individual ScalarQuantity objects for Tlist, Plist, Vlist
        if Tlist:
            Tlist = Quantity(Tlist) # Be able to create a Quantity object from it first
            Tlist = [(Tlist.value[i],Tlist.units) for i in range(len(Tlist.value))]
        if Plist:
            Plist = Quantity(Plist)
            Plist = [(Plist.value[i],Plist.units) for i in range(len(Plist.value))]
        if Vlist:
            Vlist = Quantity(Vlist)
            Vlist = [(Vlist.value[i],Vlist.units) for i in range(len(Vlist.value))]
        
        
        conditions=[]
        
    
        if Tlist is None:
            for molFrac in molFracList:
                for P in Plist:
                    for V in Vlist:
                        conditions.append(CanteraCondition(reactorType, reactionTime, molFrac, P0=P, V0=V))
    
        elif Plist is None:
            for molFrac in molFracList:
                for T in Tlist:
                    for V in Vlist:
                        conditions.append(CanteraCondition(reactorType, reactionTime, molFrac, T0=T, V0=V))
    
        elif Vlist is None:
            for molFrac in molFracList:
                for T in Tlist:
                    for P in Plist:
                        conditions.append(CanteraCondition(reactorType, reactionTime, molFrac, T0=T, P0=P))
    
        else: raise Exception("Cantera conditions must leave one of T0, P0, and V0 state variables unspecified")
        return conditions
예제 #24
0
    def simulate(self):
        """
        Run all the conditions as a cantera simulation.
        Returns the data as a list of tuples containing: (time, [list of temperature, pressure, and species data]) 
            for each reactor condition
        """
        # Get all the cantera names for the species
        speciesNamesList = [
            getSpeciesIdentifier(species) for species in self.speciesList
        ]

        allData = []
        for condition in self.conditions:

            # First translate the molFrac from species objects to species names
            newMolFrac = {}
            for key, value in condition.molFrac.iteritems():
                newkey = getSpeciesIdentifier(key)
                newMolFrac[newkey] = value

            # Set Cantera simulation conditions
            if condition.V0 is None:
                self.model.TPX = condition.T0.value_si, condition.P0.value_si, newMolFrac
            elif condition.P0 is None:
                self.model.TDX = condition.T0.value_si, 1.0 / condition.V0.value_si, newMolFrac
            else:
                raise Exception(
                    "Cantera conditions in which T0 and P0 or T0 and V0 are not the specified state variables are not yet implemented."
                )

            # Choose reactor
            if condition.reactorType == 'IdealGasReactor':
                canteraReactor = ct.IdealGasReactor(self.model)
            elif condition.reactorType == 'IdealGasConstPressureReactor':
                canteraReactor = ct.IdealConstPressureGasReactor(self.model)
            else:
                raise Exception(
                    'Other types of reactor conditions are currently not supported'
                )

            # Run this individual condition as a simulation
            canteraSimulation = ct.ReactorNet([canteraReactor])

            # Initialize the variables to be saved
            times = []
            temperature = []
            pressure = []
            speciesData = []

            # Begin integration
            time = 0.0
            # Run the simulation over 100 time points
            while canteraSimulation.time < condition.reactionTime.value_si:

                # Advance the state of the reactor network in time from the current time to time t [s], taking as many integrator timesteps as necessary.
                canteraSimulation.step(condition.reactionTime.value_si)
                times.append(canteraSimulation.time)
                temperature.append(canteraReactor.T)
                pressure.append(canteraReactor.thermo.P)
                speciesData.append(canteraReactor.thermo[speciesNamesList].X)

            # Convert speciesData to a numpy array
            speciesData = np.array(speciesData)

            # Resave data into generic data objects
            time = GenericData(label='Time', data=times, units='s')
            temperature = GenericData(label='Temperature',
                                      data=temperature,
                                      units='K')
            pressure = GenericData(label='Pressure', data=pressure, units='Pa')
            conditionData = []
            conditionData.append(temperature)
            conditionData.append(pressure)

            for index, species in enumerate(self.speciesList):
                # Create generic data object that saves the species object into the species object.  To allow easier manipulate later.
                speciesGenericData = GenericData(label=speciesNamesList[index],
                                                 species=species,
                                                 data=speciesData[:, index],
                                                 index=species.index)
                conditionData.append(speciesGenericData)

            allData.append((time, conditionData))

        return allData
예제 #25
0
species_list, reactions_list = loadChemkinFile(chemkinPath, dictionaryPath)

#generate species images
mech_path = path + '/data/' + mech
speciesPath = mech_path + '/species/'
if not os.path.isdir(speciesPath):
    os.makedirs(speciesPath)

species = species_list[:]
re_index_search = re.compile(r'\((\d+)\)$').search
for spec in species:
    match = re_index_search(spec.label)
    if match:
        spec.index = int(match.group(0)[1:-1])
        spec.label = spec.label[0:match.start()]
    # Draw molecules if necessary
    fstr = os.path.join(mech_path, 'species', '{0}.png'.format(spec))
    if not os.path.exists(fstr):
        try:
            MoleculeDrawer().draw(spec.molecule[0], 'png', fstr)
        except IndexError:
            raise OutputError("{0} species could not be drawn!".format(getSpeciesIdentifier(spec)))

species_target = 'C=CC[CH]CCCCCCC'
# search the target species in model
mol_tgt = Molecule().fromSMILES(species_target)

for spc in species_list:
    if spc.isIsomorphic(mol_tgt):
        print '{} is found in model with spc name {}'.format(mol_tgt, getSpeciesIdentifier(spc))
        break
예제 #26
0
    def simulate(self):
        """
        Run all the conditions as a cantera simulation.
        Returns the data as a list of tuples containing: (time, [list of temperature, pressure, and species data]) 
            for each reactor condition
        """
        # Get all the cantera names for the species
        speciesNamesList = [
            getSpeciesIdentifier(species) for species in self.speciesList
        ]
        inertIndexList = [
            self.speciesList.index(species) for species in self.speciesList
            if species.index == -1
        ]

        allData = []
        for condition in self.conditions:

            # First translate the molFrac from species objects to species names
            newMolFrac = {}
            for key, value in condition.molFrac.iteritems():
                newkey = getSpeciesIdentifier(key)
                newMolFrac[newkey] = value

            # Set Cantera simulation conditions
            if condition.V0 is None:
                self.model.TPX = condition.T0.value_si, condition.P0.value_si, newMolFrac
            elif condition.P0 is None:
                self.model.TDX = condition.T0.value_si, 1.0 / condition.V0.value_si, newMolFrac
            else:
                raise Exception(
                    "Cantera conditions in which T0 and P0 or T0 and V0 are not the specified state variables are not yet implemented."
                )

            # Choose reactor
            if condition.reactorType == 'IdealGasReactor':
                canteraReactor = ct.IdealGasReactor(self.model)
            elif condition.reactorType == 'IdealGasConstPressureReactor':
                canteraReactor = ct.IdealGasConstPressureReactor(
                    contents=self.model)
            elif condition.reactorType == 'IdealGasConstPressureTemperatureReactor':
                canteraReactor = ct.IdealGasConstPressureReactor(
                    contents=self.model, energy='off')
            else:
                raise Exception(
                    'Other types of reactor conditions are currently not supported'
                )

            # Run this individual condition as a simulation
            canteraSimulation = ct.ReactorNet([canteraReactor])

            numCtReactions = len(self.model.reactions())
            if self.sensitiveSpecies:
                if ct.__version__ == '2.2.1':
                    print 'Warning: Cantera version 2.2.1 may not support sensitivity analysis unless SUNDIALS was used during compilation.'
                    print 'Warning: Upgrade to newer of Cantera in anaconda using the command "conda update -c rmg cantera"'
                # Add all the reactions as part of the analysis
                for i in range(numCtReactions):
                    canteraReactor.add_sensitivity_reaction(i)
                # Set the tolerances for the sensitivity coefficients
                canteraSimulation.rtol_sensitivity = 1e-4
                canteraSimulation.atol_sensitivity = 1e-6

            # Initialize the variables to be saved
            times = []
            temperature = []
            pressure = []
            speciesData = []
            sensitivityData = []

            # Begin integration
            time = 0.0
            # Run the simulation over 100 time points
            while canteraSimulation.time < condition.reactionTime.value_si:

                # Advance the state of the reactor network in time from the current time to time t [s], taking as many integrator timesteps as necessary.
                canteraSimulation.step(condition.reactionTime.value_si)
                times.append(canteraSimulation.time)
                temperature.append(canteraReactor.T)
                pressure.append(canteraReactor.thermo.P)
                speciesData.append(canteraReactor.thermo[speciesNamesList].X)

                if self.sensitiveSpecies:
                    # Cantera returns mass-based sensitivities rather than molar concentration or mole fraction based sensitivities.
                    # The equation for converting between them is:
                    #
                    # d ln xi = d ln wi - sum_(species i) (dln wi) (xi)
                    #
                    # where xi is the mole fraction of species i and wi is the mass fraction of species i

                    massFracSensitivityArray = canteraSimulation.sensitivities(
                    )
                    if condition.reactorType == 'IdealGasReactor':
                        # Row 0: mass, Row 1: volume, Row 2: internal energy or temperature, Row 3+: mass fractions of species
                        massFracSensitivityArray = massFracSensitivityArray[
                            3:, :]
                    elif condition.reactorType == 'IdealGasConstPressureReactor' or condition.reactorType == 'IdealGasConstPressureTemperatureReactor':
                        # Row 0: mass, Row 1: enthalpy or temperature, Row 2+: mass fractions of the species
                        massFracSensitivityArray = massFracSensitivityArray[
                            2:, :]
                    else:
                        raise Exception(
                            'Other types of reactor conditions are currently not supported'
                        )

                    for i in range(len(massFracSensitivityArray)):
                        massFracSensitivityArray[i] *= speciesData[-1][i]

                    sensitivityArray = np.zeros(
                        len(self.sensitiveSpecies) *
                        len(self.model.reactions()))
                    for index, species in enumerate(self.sensitiveSpecies):
                        for j in range(numCtReactions):
                            sensitivityArray[
                                numCtReactions * index +
                                j] = canteraSimulation.sensitivity(
                                    species.toChemkin(), j)

                            for i in range(len(massFracSensitivityArray)):
                                if i not in inertIndexList:
                                    # massFracSensitivity for inerts are returned as nan in Cantera, so we must not include them here
                                    sensitivityArray[
                                        numCtReactions * index +
                                        j] -= massFracSensitivityArray[i][j]
                    sensitivityData.append(sensitivityArray)

            # Convert speciesData and sensitivityData to a numpy array
            speciesData = np.array(speciesData)
            sensitivityData = np.array(sensitivityData)

            # Resave data into generic data objects
            time = GenericData(label='Time', data=times, units='s')
            temperature = GenericData(label='Temperature',
                                      data=temperature,
                                      units='K')
            pressure = GenericData(label='Pressure', data=pressure, units='Pa')
            conditionData = []
            conditionData.append(temperature)
            conditionData.append(pressure)

            for index, species in enumerate(self.speciesList):
                # Create generic data object that saves the species object into the species object.  To allow easier manipulate later.
                speciesGenericData = GenericData(label=speciesNamesList[index],
                                                 species=species,
                                                 data=speciesData[:, index],
                                                 index=species.index)
                conditionData.append(speciesGenericData)

            reactionSensitivityData = []
            for index, species in enumerate(self.sensitiveSpecies):
                for j in range(numCtReactions):
                    reactionSensitivityGenericData = GenericData(
                        label='dln[{0}]/dln[k{1}]: {2}'.format(
                            species.toChemkin(), j + 1,
                            self.model.reactions()[j]),
                        species=species,
                        reaction=self.model.reactions()[j],
                        data=sensitivityData[:, numCtReactions * index + j],
                        index=j + 1,
                    )
                    reactionSensitivityData.append(
                        reactionSensitivityGenericData)

            allData.append((time, conditionData, reactionSensitivityData))

        return allData
예제 #27
0
파일: flux.py 프로젝트: nyee/PyChemkin
def extractROPData(ckcsvFile, species='', speciesList=[], reactionList=[]):
    """
    Extract the ROP information from a chemkin run for a single species.
    Returns a list of SpeciesROP objects. Will only return a list containing a single SpeciesROP object
    if there are no continuations.
    
    Will also identify corresponding species and reaction objects from a loaded Chemkin file if 
    speciesList and reactionList are given.
    """
    from rmgpy.chemkin import getSpeciesIdentifier
    # Pre-convert the speciesList and reactionList to strings
    speciesStringList = []
    if speciesList:
        for spec in speciesList:
            speciesStringList.append(getSpeciesIdentifier(spec))

    reactionStringList = []
    if reactionList:
        for rxn in reactionList:
            rxnString = rxn.toChemkin(kinetics=False)
            if rxn.reversible:
                rxnString = rxnString.replace('=', '<=>')
            reactionStringList.append(rxnString)

    timeData = {}
    distanceData = {}
    speciesROPData = {}

    with open(ckcsvFile, 'r') as stream:
        reader = csv.reader(stream)

        for row in reader:
            label = row[0].strip()
            tokens = label.split('_')
            if tokens[0] == 'Time':
                if 'Soln' in tokens[-1]:
                    tsolnNumber = int(tokens[-1].split('#')[-1])
                else:
                    tsolnNumber = 0
                tdata = numpy.array([float(r) for r in row[2:]], numpy.float)
                tunits = row[1].strip()[1:-1].lower()
                tdata *= {
                    'sec': 1.0,
                    'min': 60.,
                    'hr': 3600.,
                    'msec': 1e-3,
                    'microsec': 1e-6
                }[tunits]
                timeData[tsolnNumber] = tdata
                continue

            if tokens[0] == 'Distance':
                if 'Soln' in tokens[-1]:
                    dsolnNumber = int(tokens[-1].split('#')[-1])
                else:
                    dsolnNumber = 0
                ddata = numpy.array([float(r) for r in row[2:]], numpy.float)
                dunits = row[1].strip()[1:-1].lower()
                ddata *= {'cm': 1.0, 'mm': 0.1, 'm': 100.}[dunits]
                distanceData[dsolnNumber] = ddata
                continue

            if len(tokens) > 1:
                if tokens[1] == 'ROP':
                    species_string = tokens[0]
                    if species == species_string:
                        # Create a SpeciesROP object for this solution number
                        if 'Soln' in tokens[-1]:
                            solutionNumber = int(tokens[-1].split('#')[-1])
                        else:
                            # Only 1 solution set
                            solutionNumber = 0
                        if solutionNumber not in speciesROPData.keys():
                            speciesROPData[solutionNumber] = SpeciesROP(
                                species, ropData=[])
                            if speciesList:
                                speciesROPData[solutionNumber].identifySpecies(
                                    speciesList, speciesStringList)
                        if tokens[3] == 'Total':
                            # Total ROP rate
                            speciesROPData[
                                solutionNumber].totalRopData = numpy.array(
                                    [float(r) for r in row[2:]], numpy.float)
                        else:
                            rxnString = tokens[2]
                            rxnNumber = int(tokens[3].split('#')[-1])
                            rxnRopData = numpy.array(
                                [float(r) for r in row[2:]], numpy.float)
                            dataObject = ReactionROP(rxnString=rxnString,
                                                     rxnNumber=rxnNumber,
                                                     data=rxnRopData)
                            if reactionList:
                                dataObject.identifyReaction(
                                    reactionList, reactionStringList)
                            speciesROPData[solutionNumber].ropData.append(
                                dataObject)

    speciesROPList = []
    if timeData:
        if len(timeData) != len(speciesROPData):
            raise Exception(
                'Number of time and ROP data sets are mismatched.  Something went wrong during parsing'
            )
        else:
            for solutionNumber in sorted(speciesROPData.keys()):
                speciesROP = speciesROPData[solutionNumber]
                speciesROP.xvarData = timeData[solutionNumber]
                speciesROPList.append(speciesROP)

    elif distanceData:
        if len(distanceData) != len(speciesROPData):
            raise Exception(
                'Number of time and ROP data sets are mismatched.  Something went wrong during parsing'
            )
        else:
            for solutionNumber in sorted(speciesROPData.keys()):
                speciesROP = speciesROPData[solutionNumber]
                speciesROP.xvarData = distanceData[solutionNumber]
                speciesROPList.append(speciesROP)

    else:
        raise Exception(
            'Did not parse any time or distance data.  Something went wrong during parsing or simulation'
        )

    return speciesROPList
예제 #28
0
파일: output.py 프로젝트: olusade/RMG-Py
def saveDiffHTML(path, commonSpeciesList, speciesList1, speciesList2,
                 commonReactions, uniqueReactions1, uniqueReactions2):
    """
    This function outputs the species and reactions on an HTML page
    for the comparison of two RMG models.
    """
    from model import PDepReaction
    from rmgpy.kinetics import Arrhenius, MultiArrhenius, MultiPDepArrhenius

    from rmgpy.molecule.draw import MoleculeDrawer
    try:
        import jinja2
    except ImportError:
        logging.warning(
            "jinja package not found; HTML output will not be saved.")
        return

    path = os.path.abspath(path)
    dirname = os.path.dirname(path)

    # Prepare parameters to pass to jinja template
    title = 'RMG Model Comparison'

    speciesList = [spec1 for spec1, spec2 in commonSpeciesList] + [
        spec2 for spec1, spec2 in commonSpeciesList
    ] + speciesList1 + speciesList2
    re_index = re.compile(r'\((\d+)\)$')

    if not os.path.isdir(os.path.join(dirname, 'species1')):
        os.makedirs(os.path.join(dirname, 'species1'))

    if not os.path.isdir(os.path.join(dirname, 'species2')):
        os.makedirs(os.path.join(dirname, 'species2'))

    for spec1, spec2 in commonSpeciesList:
        # if the species dictionary came from an RMG-Java job, make them prettier
        # We use the presence of a trailing index on the label to discern this
        # (A single open parenthesis is not enough (e.g. when using SMILES strings as labels!)
        match1 = re_index.search(spec1.label)
        if match1:
            spec1.index = int(match1.group(0)[1:-1])
            spec1.label = spec1.label[0:match1.start()]

        match2 = re_index.search(spec2.label)
        if match2:
            spec2.index = int(match2.group(0)[1:-1])
            spec2.label = spec2.label[0:match2.start()]

        # Draw molecules if necessary
        fstr = os.path.join(dirname, 'species1', '{0}.png'.format(spec1))
        if not os.path.exists(fstr):
            try:
                MoleculeDrawer().draw(spec1.molecule[0], 'png', fstr)
            except IndexError:
                raise OutputError(
                    '{0} species could not be drawn because it did not contain a molecular structure. Please recheck your files.'
                    .format(getSpeciesIdentifier(spec1)))

        fstr = os.path.join(dirname, 'species2', '{0}.png'.format(spec2))
        if not os.path.exists(fstr):
            try:
                MoleculeDrawer().draw(spec2.molecule[0], 'png', fstr)
            except IndexError:
                raise OutputError(
                    '{0} species could not be drawn because it did not contain a molecular structure. Please recheck your files.'
                    .format(getSpeciesIdentifier(spec2)))

    for spec in speciesList1:
        match = re_index.search(spec.label)
        if match:
            spec.index = int(match.group(0)[1:-1])
            spec.label = spec.label[0:match.start()]
        # Draw molecules if necessary
        fstr = os.path.join(dirname, 'species1', '{0}.png'.format(spec))
        if not os.path.exists(fstr):
            try:
                MoleculeDrawer().draw(spec.molecule[0], 'png', fstr)
            except IndexError:
                raise OutputError(
                    '{0} species could not be drawn because it did not contain a molecular structure. Please recheck your files.'
                    .format(getSpeciesIdentifier(spec)))

    for spec in speciesList2:
        match = re_index.search(spec.label)
        if match:
            spec.index = int(match.group(0)[1:-1])
            spec.label = spec.label[0:match.start()]
        # Draw molecules if necessary
        fstr = os.path.join(dirname, 'species2', '{0}.png'.format(spec))
        if not os.path.exists(fstr):
            try:
                MoleculeDrawer().draw(spec.molecule[0], 'png', fstr)
            except IndexError:
                raise OutputError(
                    '{0} species could not be drawn because it did not contain a molecular structure. Please recheck your files.'
                    .format(getSpeciesIdentifier(spec)))

    familyCount1 = {}
    familyCount2 = {}
    for rxn1, rxn2 in commonReactions:
        if isinstance(rxn2.kinetics, (MultiArrhenius, MultiPDepArrhenius)):
            rxn2.duplicate = True
        if isinstance(rxn1, PDepReaction):
            family = "PDepNetwork"
        else:
            family = rxn1.getSource().label
        if family in familyCount1:
            familyCount1[family] += 1
            familyCount2[family] += 1
        else:
            familyCount1[family] = 1
            familyCount2[family] = 1

    for rxn in uniqueReactions1:
        if isinstance(rxn, PDepReaction):
            family = "PDepNetwork"
        else:
            family = rxn.getSource().label
        if family in familyCount1:
            familyCount1[family] += 1
        else:
            familyCount1[family] = 1

    for rxn in uniqueReactions2:
        if isinstance(rxn, PDepReaction):
            family = "PDepNetwork"
        else:
            family = rxn.getSource().label
        if family in familyCount2:
            familyCount2[family] += 1
        else:
            familyCount2[family] = 1

    families1 = familyCount1.keys()
    families2 = familyCount2.keys()
    families1.sort()
    families2.sort()

    ## jinja2 filters etc.
    to_remove_from_css_names = re.compile('[/.\-+,]')

    def csssafe(input):
        "Replace unsafe CSS class name characters with an underscore."
        return to_remove_from_css_names.sub('_', input)

    environment = jinja2.Environment()
    environment.filters['csssafe'] = csssafe

    # Make HTML file
    template = environment.from_string(
        """<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
    <title>{{ title }}</title>
    <style type="text/css">
        body {
            font-family: sans-serif;
        }
        a {
            color: #993333;
            text-decoration: none;
        }
        a:visited {
            color: #993333;
        }
        a:hover {
            text-decoration: underline;
        }
        table.speciesList, table.reactionList {
            width: 100%;
            border-collapse: collapse;
        }
        table.speciesList th, table.reactionList th {
            text-align: left;
        }
        tr.reaction td {
            border-top: 1px solid #808080;
        }
        td.reactants {
            text-align: right;
        }
        td.products {
            text-align: left;
        }
        td.reactionArrow {
            text-align: center;
            font-size: 16px;
        }
        td.species img, td.reactants img, td.products img {
            vertical-align: middle;
        }
        tr.comment {
            font-size: small;
        }
        tr.kinetics {
            font-size: small;
        }
        .KineticsData {
            # border: 1px solid gray;
        }
        .KineticsData th {
            width: 15em;
            word-wrap: none;
        }
        .KineticsData td {
            width: 3em;
        }

        .chemkin, .KineticsData_repr {
           white-space: pre-wrap;
           font-size: x-small;
           font-family: "Andale Mono", monospace;
        }

        .hide_comment .comment{
            display: none !important;
        }
        .hide_kinetics .kinetics{
           display: none !important;
        }
        .hide_chemkin .chemkin{
           display: none !important;
        }
    </style>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.1/jquery.min.js"></script>
    <script type="text/javascript" src="../../../external/jquery.min.js"></script>
    <script type="text/javascript">
    function updateFamily(family) {
        if (family.checked) {
            $("."+family.value).show();
        } else {
            $("."+family.value).hide();
        }
    }
    function updateDetails(type) {
        if (type.checked) {
            $(".reactionList").removeClass("hide_"+type.value);
        } else {
            $(".reactionList").addClass("hide_"+type.value);
        }
    }
    function checkAllFamilies() {
        $("#familySelector").find("[name='family']").each(function() { this.checked = true; updateFamily(this); });
        return false;
    }
    function uncheckAllFamilies() {
        $("#familySelector").find("[name='family']").each(function() { this.checked = false; updateFamily(this); });
        return false;
    }
    function checkAllDetails() {
        $("#familySelector").find("[name='detail']").each(function() { this.checked = true; updateDetails(this); });
        return false;
    }
    function uncheckAllDetails() {
        $("#familySelector").find("[name='detail']").each(function() { this.checked = false; updateDetails(this); });
        return false;
    }
    $(document).ready(function() {
        checkAllFamilies();
        uncheckAllDetails();
    });

    </script>
</head>

<body>

<h1>{{ title }}</h1>

<h2 align="center">Common Species ({{ commonSpecies|length }})</h2>

<table width="100%">
    {% for spec1, spec2 in commonSpecies %}
    <tr>
        <td width="100%" colspan="4">
            <table align="center">
                <tr class="species">
                    <td>{{ spec1.label }}</td>
                    <td class="structure" align="center"><a href="{{spec1.molecule[0].getURL()}}"><img src="species1/{{ spec1|replace('#','%23') }}.png" alt="{{ spec1 }}" title="{{ spec1 }}"></a></td>
                    <td>{{ "%.2f"|format(spec1.molecule[0].getMolecularWeight() * 1000) }}</td>
                </tr>
            </table>
        </td>
    </tr>
    {% if spec1.thermo and spec2.thermo %}
    {% if spec1.thermo.isIdenticalTo(spec2.thermo) %}
    <tr width=100%>
         <td colspan="4" valign="top" width=50%><div align="center"><font color="blue">IDENTICAL THERMO WAS FOUND FOR THIS SPECIES.</font></div>
    </tr>
    {% elif spec1.thermo.isSimilarTo(spec2.thermo) %}
    <tr width=100%>
         <td colspan="4" valign="top" width=50%><div align="center"><font color="green">SIMILAR THERMO WAS FOUND FOR THIS SPECIES.</font></div>
    </tr>
    {% else %}
     <tr width=100%>
         <td colspan="4" valign="top" width=50%><div align="center"><font color="red">DIFFERENT THERMO WAS FOUND FOR THIS SPECIES.</font></div>
    </tr>
    {% endif%}
    <tr>
        <td width="10%">{{ spec1.index }}. </td>
        <td width="40%">
            <table width="100%">
                <tr>
                    <th>H300</th>
                    <th>S300</th>
                    <th>Cp300</th>
                    <th>Cp500</th>
                    <th>Cp1000</th>
                    <th>Cp1500</th>
                </tr>
                <tr>
                    <td>{% if spec1.thermo.Tmin.value_si <= 300 %}
                    {{ "%.2f"|format(spec1.thermo.getEnthalpy(300) / 4184) }}
                    {% endif %}</td>
                    <td>
                    {% if spec1.thermo.Tmin.value_si <= 300 %}
                    {{ "%.2f"|format(spec1.thermo.getEntropy(300) / 4.184) }}
                    {% endif %}</td>
                    <td>{{ "%.2f"|format(spec1.thermo.getHeatCapacity(300) / 4.184) }}</td>
                    <td>{{ "%.2f"|format(spec1.thermo.getHeatCapacity(500) / 4.184) }}</td>
                    <td>{{ "%.2f"|format(spec1.thermo.getHeatCapacity(1000) / 4.184) }}</td>
                    <td>{{ "%.2f"|format(spec1.thermo.getHeatCapacity(1500) / 4.184) }}</td>
                </tr>
            </table>
        </td>
        <td width="10%">{{ spec2.index }}.</td>
        <td width="40%">
            <table width="100%">
                <tr>
                    <th>H300</th>
                    <th>S300</th>
                    <th>Cp300</th>
                    <th>Cp500</th>
                    <th>Cp1000</th>
                    <th>Cp1500</th>
                </tr>
                <tr>
                    <td>{% if spec2.thermo.Tmin.value_si <= 300 %}
                    {{ "%.2f"|format(spec2.thermo.getEnthalpy(300) / 4184) }}
                    {% endif %}</td>
                    <td>{% if spec2.thermo.Tmin.value_si <= 300 %}
                    {{ "%.2f"|format(spec2.thermo.getEntropy(300) / 4.184) }}
                    {% endif %}</td>
                    <td>{{ "%.2f"|format(spec2.thermo.getHeatCapacity(300) / 4.184) }}</td>
                    <td>{{ "%.2f"|format(spec2.thermo.getHeatCapacity(500) / 4.184) }}</td>
                    <td>{{ "%.2f"|format(spec2.thermo.getHeatCapacity(1000) / 4.184) }}</td>
                    <td>{{ "%.2f"|format(spec2.thermo.getHeatCapacity(1500) / 4.184) }}</td>
                </tr>
            </table>
        </td>
    </tr>
    {% endif %}
    <tr>
        <td width="100%" colspan="4"><hr/></td>
    </tr>
    {% endfor %}
</table>

<table width=100%>
<tr colspan="2">
<td width=50% valign="top">

<h2>Model 1: Unique Species ({{ speciesList1|length }})</h2>
<table class="speciesList">
    <tr><th>Index</th><th>Structure</th><th>Label</th><th>Mol. Wt. (g/mol)</th></tr>
    {% for spec in speciesList1 %}
    <tr class="species">
        <td class="index">
        {{ spec.index }}.</td>
        <td class="structure"><a href="{{ spec.molecule[0].getURL() }}"><img src="species1/{{ spec|replace('#','%23') }}.png" alt="{{ spec }}" title="{{ spec }}"></a></td>
        <td class="label">{{ spec.label }}</td>
        <td>{{ "%.2f"|format(spec.molecule[0].getMolecularWeight() * 1000) }}</td>
    </tr>
    {% endfor %}
</table>
</td>
<td width=50% valign="top">
<h2>Model 2: Unique Species ({{ speciesList2|length }})</h2>
<table class="speciesList">
    <tr><th>Index</th><th>Structure</th><th>Label</th><th>Mol. Wt. (g/mol)</th></tr>
    {% for spec in speciesList2 %}
    <tr class="species">
        <td class="index">
        {{ spec.index }}.</td>
        <td class="structure"><a href="{{ spec.molecule[0].getURL() }}"><img src="species2/{{ spec|replace('#','%23') }}.png" alt="{{ spec }}" title="{{ spec }}"></a></td>
        <td class="label">{{ spec.label }}</td>
        <td>{{ "%.2f"|format(spec.molecule[0].getMolecularWeight() * 1000) }}</td>
    </tr>
    {% endfor %}
</table>
</td></tr>

<tr colspan="2">
<td width=50% valign="top">
<h2>Model 1 Reactions ({{ commonReactions|length + uniqueReactions1|length}})</h2>

<form id='familySelector' action="">
    <h4>Reaction families:</h4>
{% for family in families1 %}    <input type="checkbox" id="{{ family|csssafe }}" name="family" value="{{ family|csssafe }}" checked="checked" onclick="updateFamily(this);"><label for="{{ family|csssafe }}">{{ family }} ({{ familyCount1[family] }} rxn{{ 's' if familyCount1[family] != 1 }})</label><br>
{% endfor %}
    <a href="javascript:checkAllFamilies();" onclick="checkAllFamilies()">check all</a> &nbsp; &nbsp; <a href="javascript:uncheckAllFamilies();" onclick="uncheckAllFamilies();">uncheck all</a><br>

    <h4>Reaction Details:</h4>
    <input type="checkbox" id="kinetics" name="detail" value="kinetics" onclick="updateDetails(this);"><label for="kinetics">Kinetics</label><br>
    <input type="checkbox" id="comment" name="detail" value="comment" onclick="updateDetails(this);"><label for="comment">Comments</label><br>
    <input type="checkbox" id="chemkin" name="detail" value="chemkin" onclick="updateDetails(this);"><label for="chemkin">Chemkin strings</label><br>
    <a href="javascript:checkAllDetails();" onclick="checkAllDetails()">check all</a> &nbsp; &nbsp; <a href="javascript:uncheckAllDetails();" onclick="uncheckAllDetails();">uncheck all</a>
</form>
</td>

<td width=50% valign="top">
<h2>Model 2 Reactions ({{ commonReactions|length +uniqueReactions2|length}})</h2>

<form id='familySelector' action="">
    <h4>Reaction families:</h4>
{% for family in families2 %}    <input type="checkbox" id="{{ family|csssafe }}" name="family" value="{{ family|csssafe }}" checked="checked" onclick="updateFamily(this);"><label for="{{ family|csssafe }}">{{ family }} ({{ familyCount2[family] }} rxn{{ 's' if familyCount2[family] != 1 }})</label><br>
{% endfor %}
    <a href="javascript:checkAllFamilies();" onclick="checkAllFamilies()">check all</a> &nbsp; &nbsp; <a href="javascript:uncheckAllFamilies();" onclick="uncheckAllFamilies();">uncheck all</a><br>

    <h4>Reaction Details:</h4>
    <input type="checkbox" id="kinetics" name="detail" value="kinetics" onclick="updateDetails(this);"><label for="kinetics">Kinetics</label><br>
    <input type="checkbox" id="comment" name="detail" value="comment" onclick="updateDetails(this);"><label for="comment">Comments</label><br>
    <input type="checkbox" id="chemkin" name="detail" value="chemkin" onclick="updateDetails(this);"><label for="chemkin">Chemkin strings</label><br>
    <a href="javascript:checkAllDetails();" onclick="checkAllDetails()">check all</a> &nbsp; &nbsp; <a href="javascript:uncheckAllDetails();" onclick="uncheckAllDetails();">uncheck all</a>
</form>
</td>
</tr>

</table>


<table width=100%>
<tr><td width=100% align="center">
<h2>Common Reactions ({{ commonReactions|length}})</h2></td></tr>


<tr colspan="1"><td width=100%>

<table class="reactionList hide_comment hide_kinetics hide_chemkin" width=100% cellpadding="10">
    <tr colspan="4" width=100%><th>Index.</th><th>Family</th><th>Index.</th><th>Family</th></tr>

    {% for rxn1, rxn2 in commonReactions %}

<tr>
<td width=100% colspan="4"><hr>
<table align="center">
<tr>
    <td class="reactants" align="right">{% for reactant in rxn1.reactants %}<a href="{{reactant.molecule[0].getURL() }}"><img src="species1/{{ reactant|replace('#','%23') }}.png" alt="{{ reactant }}" title="{{ reactant }}, MW = {{ "%.2f"|format(reactant.molecule[0].getMolecularWeight() * 1000) }}"></a>{% if not loop.last %} + {% endif %}{% endfor %}</td>
    <td class="reactionArrow" align="center">{% if rxn1.reversible %}&hArr;{% else %}&rarr;{% endif %}</td>
    <td class="products" align="left">{% for product in rxn1.products %}<a href="{{product.molecule[0].getURL()}}"><img src="species1/{{ product|replace('#','%23') }}.png" alt="{{ product }}" title="{{ product }}, MW = {{ "%.2f"|format(product.molecule[0].getMolecularWeight() * 1000) }}"></a>{% if not loop.last %} + {% endif %}{% endfor %}</td>
</tr>
</table>
</td>
</tr>


{% if rxn1.kinetics.isIdenticalTo(rxn2.kinetics) %}

 <tr width=100%>
     <td colspan="4" valign="top" width=50%><div align="center"><font color="blue">IDENTICAL KINETICS WERE FOUND FOR THIS REACTION.</font></div>

</tr>
{% elif rxn1.kinetics.isSimilarTo(rxn2.kinetics) %}

 <tr width=100%>
     <td colspan="4" valign="top" width=50%><div align="center"><font color="green">SIMILAR KINETICS WERE FOUND FOR THIS REACTION.</font></div>

</tr>

{% else %}
     <tr width=100%>
         <td colspan="4" valign="top" width=50%><div align="center"><font color="red">DIFFERENT KINETICS WERE FOUND FOR THIS REACTION.</font></div>
    </tr>
{% endif%}


<tr width=100%>
     <td class="index" width=10%><a href="{{ rxn1.getURL() }}" title="Search on RMG website" class="searchlink">{{ rxn1.index }}.</a></td>
     <td class="family" width=40%>{{ rxn1.getSource().label }}</td>

     <td class="index" width=10%><a href="{{ rxn2.getURL() }}" title="Search on RMG website" class="searchlink">{{ rxn2.index }}.</a></td>
     <td class="family" width=40%>{{ rxn2.getSource().label }}</td>
 </tr>

<tr width=100%>{% if not rxn1.isIsomorphic(rxn2, eitherDirection=False) %} 
<td colspan="2" width=50%></td>
<td colspan="2" width=50%>* Reaction was found in reverse 


{% if not rxn2.duplicate %}
<P><b>Fitted Reverse Kinetics:</b>
{% if not rxn2.kinetics.isPressureDependent() %}
{{rxn2.generateReverseRateCoefficient().toHTML() }}
{% else %} Pressure dependent
{% endif %}
{% endif %}

<P><b>Original Kinetics:</b>
{% endif %}</td>
</tr>

<tr width=100%>
     <td colspan="2" valign="top" width=50%>
     
     {{ rxn1.kinetics.toHTML() }}</td>
     <td colspan="2" valign="top" width=50%>
     {{ rxn2.kinetics.toHTML() }}</td>
</tr>

<tr width=100%>
    <td colspan="2" valign="top" width=50%><font size="1pt" face="courier">{{ rxn1.toChemkin(speciesList) }}</font></td>
    <td colspan="2" valign="top" width=50%><font size="1pt" face="courier">{{ rxn2.toChemkin(speciesList) }}</font></td>
</tr>

<tr width=100%>
    <td colspan="2" valign="top" width=50%><font size="1pt">{{ rxn1.kinetics.comment }}</font></td>
    <td colspan="2" valign="top" width=50%><font size="1pt">{{ rxn2.kinetics.comment }}</font></td>
</tr>
{% endfor %}

</table>
</td></tr></table>

<table>
<tr>
<td width=50% valign="top">
<h2>Model 1: Unique Reactions ({{ uniqueReactions1|length}})</h2>

<table class="reactionList hide_comment hide_kinetics hide_chemkin">
    <tr><th>Index</th><th colspan="3" style="text-align: center;">Reaction</th><th>Family</th></tr>
    {% for rxn in uniqueReactions1 %}
    <tr class="reaction {{ rxn.getSource().label|csssafe }}">
        <td class="index"><a href="{{ rxn.getURL() }}" title="Search on RMG website" class="searchlink">{{ rxn.index }}.</a></td>
        <td class="reactants">{% for reactant in rxn.reactants %}<a href="{{ reactant.molecule[0].getURL() }}"><img src="species1/{{ reactant|replace('#','%23') }}.png" alt="{{ reactant }}" title="{{ reactant }}, MW = {{ "%.2f"|format(reactant.molecule[0].getMolecularWeight() * 1000) }}"></a>{% if not loop.last %} + {% endif %}{% endfor %}</td>
        <td class="reactionArrow">{% if rxn.reversible %}&hArr;{% else %}&rarr;{% endif %}</td>
        <td class="products">{% for product in rxn.products %}<a href="{{ product.molecule[0].getURL() }}"><img src="species1/{{ product|replace('#','%23') }}.png" alt="{{ product }}" title="{{ product }}, MW = {{ "%.2f"|format(product.molecule[0].getMolecularWeight() * 1000) }}"></a>{% if not loop.last %} + {% endif %}{% endfor %}</td>
        <td class="family">{{ rxn.getSource().label }}</td>
    </tr>
    <tr class="kinetics {{ rxn.getSource().label|csssafe }}">
        <td></td>
        <td colspan="4">{{ rxn.kinetics.toHTML() }}</td>
    </tr>
    <tr class="chemkin {{ rxn.getSource().label|csssafe }}">
        <td></td>
        <td colspan="4">{{ rxn.toChemkin(species) }}</td>
    </tr>
    <tr class="comment {{ rxn.getSource().label|csssafe }}">
        <td></td>
        <td colspan="4">{{ rxn.kinetics.comment }}</td>
    </tr>
    {% endfor %}
    </table>

</td>

<td width=50% valign="top">
<h2>Model 2: Unique Reactions ({{ uniqueReactions2|length}})</h2>

<table class="reactionList hide_comment hide_kinetics hide_chemkin">
    <tr><th>Index</th><th colspan="3" style="text-align: center;">Reaction</th><th>Family</th></tr>
    {% for rxn in uniqueReactions2 %}
    <tr class="reaction {{ rxn.getSource().label|csssafe }}">
        <td class="index"><a href="{{ rxn.getURL() }}" title="Search on RMG website" class="searchlink">{{ rxn.index }}.</a></td>
        <td class="reactants">{% for reactant in rxn.reactants %}<a href="{{ reactant.molecule[0].getURL() }}"><img src="species2/{{ reactant|replace('#','%23') }}.png" alt="{{ reactant }}" title="{{ reactant }}, MW = {{ "%.2f"|format(reactant.molecule[0].getMolecularWeight() * 1000) }}"></a>{% if not loop.last %} + {% endif %}{% endfor %}</td>
        <td class="reactionArrow">{% if rxn.reversible %}&hArr;{% else %}&rarr;{% endif %}</td>
        <td class="products">{% for product in rxn.products %}<a href="{{ product.molecule[0].getURL() }}"><img src="species2/{{ product|replace('#','%23') }}.png" alt="{{ product }}" title="{{ product }}, MW = {{ "%.2f"|format(product.molecule[0].getMolecularWeight() * 1000) }}"></a>{% if not loop.last %} + {% endif %}{% endfor %}</td>
        <td class="family">{{ rxn.getSource().label }}</td>
    </tr>
    <tr class="kinetics {{ rxn.getSource().label|csssafe }}">
        <td></td>
        <td colspan="4">{{ rxn.kinetics.toHTML() }}</td>
    </tr>
    <tr class="chemkin {{ rxn.getSource().label|csssafe }}">
        <td></td>
        <td colspan="4">{{ rxn.toChemkin(species) }}</td>
    </tr>
    <tr class="comment {{ rxn.getSource().label|csssafe }}">
        <td></td>
        <td colspan="4">{{ rxn.kinetics.comment }}</td>
    </tr>
    {% endfor %}
    </table>

</td>

</table>



</body>

</html>
""")
    f = open(path, 'w')
    f.write(
        template.render(title=title,
                        commonSpecies=commonSpeciesList,
                        speciesList1=speciesList1,
                        speciesList2=speciesList2,
                        commonReactions=commonReactions,
                        uniqueReactions1=uniqueReactions1,
                        uniqueReactions2=uniqueReactions2,
                        families1=families1,
                        families2=families2,
                        familyCount1=familyCount1,
                        familyCount2=familyCount2,
                        speciesList=speciesList))
    f.close()
예제 #29
0
파일: flux.py 프로젝트: nyee/PyChemkin
def saveFluxAnalysisHTML(path,
                         idx,
                         speciesROP,
                         negativeROPList=[],
                         positiveROPList=[],
                         speciesList=[]):
    """
    Save the flux analysis for a given species to HTML.
    """
    import os
    from rmgpy.molecule.draw import MoleculeDrawer
    from rmgpy.chemkin import getSpeciesIdentifier
    from .html import renderSpecies, renderReactionROP, STYLE_HEADER

    try:
        import jinja2
    except ImportError:
        print "jinja2 package not found; HTML output will not be saved."
        return

    path = os.path.abspath(path)
    dirname = os.path.dirname(path)

    if not os.path.isdir(os.path.join(dirname, 'species')):
        os.makedirs(os.path.join(dirname, 'species'))

    for spec in speciesList:
        # Draw molecules
        speciesLabel = getSpeciesIdentifier(spec)
        fstr = os.path.join(dirname, 'species', '{0}.png'.format(speciesLabel))
        if not os.path.exists(fstr):
            try:
                MoleculeDrawer().draw(spec.molecule[0], 'png', fstr)
            except IndexError:
                raise Exception(
                    "{0} species could not be drawn because it did not contain a molecular structure. Please recheck your files."
                    .format(speciesLabel))

    #title = 'Flux Analysis for Species {label} at x = {x}'.format(label=getSpeciesIdentifier(species), x=speciesROP.xvarData[idx])
    #self.totalNegativeRate[idx]
    #print '{num}. {rxnString}\t Actual flux = {flux}\t % of Total Positive ROP = {fluxpercent}'.format(num=i+1, rxnString=rxnRop.rxnString, flux=rxnRop.data[idx], fluxpercent=rxnRop.fluxPercentage[idx])

    environment = jinja2.Environment()
    environment.filters['renderSpecies'] = renderSpecies
    environment.filters['renderReactionROP'] = renderReactionROP
    environment.filters['getSpeciesIdentifier'] = getSpeciesIdentifier

    # Make HTML file
    template = environment.from_string(
        """<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
<title>Flux Analysis for Species {{speciesROP.speciesObject|getSpeciesIdentifier}} at x = {{speciesROP.xvarData[idx]}}</title>
{{style}}
</head>
<body>
<h1>Flux Analysis for Species {{speciesROP.speciesObject|getSpeciesIdentifier}} at x = {{speciesROP.xvarData[idx]}}</h1>
<h2>Species</h2>

<table class="speciesList">
<tr><th>Label</th><th>Structure</th><th>SMILES</th><th>Thermo</th>
{{speciesROP.speciesObject|renderSpecies(thermo=True)}}
</table>
<hr>

<h3>Net ROP = {{speciesROP.totalRopData[idx]}}</h3>

<hr size=3>
<h2>Top Negative Flux Reactions Depleting Species {{speciesROP.speciesObject|getSpeciesIdentifier}}</h2>
<h3>Total Negative ROP = {{speciesROP.totalNegativeRate[idx]}}</h3>

<table class="reactionList" hide_comment hide_kinetics hide_chemkin">
{% for rxnROP in negativeROPList %}
{{rxnROP|renderReactionROP(speciesList, showROP=True, idx=idx)}}
{% endfor %}
</table>

<hr size=3>
<h2>Top Positive Flux Reactions Accumulating Species {{speciesROP.speciesObject|getSpeciesIdentifier}}</h2>
<h3>Total Positive ROP = {{speciesROP.totalPositiveRate[idx]}}</h3>

<table class="reactionList" hide_comment hide_kinetics hide_chemkin">
{% for rxnROP in positiveROPList %}
{{rxnROP|renderReactionROP(speciesList, showROP=True, idx=idx)}}
{% endfor %}
</table>

</body>
</html>
""")

    f = open(path, 'w')
    f.write(
        template.render(style=STYLE_HEADER,
                        idx=idx,
                        speciesROP=speciesROP,
                        negativeROPList=negativeROPList,
                        positiveROPList=positiveROPList,
                        speciesList=speciesList))
    f.close()
예제 #30
0
파일: output.py 프로젝트: vrlambert/RMG-Py
def saveOutputHTML(path, reactionModel):
    """
    Save the current set of core species and reactions of `reactionModel` to
    an HTML file `path` on disk. As part of this process, drawings of all core
    species are created in the species folder (if they don't already exist)
    using the :mod:`rmgpy.molecule.draw` module. The :mod:`jinja`
    package is used to generate the HTML; if this package is not found, no
    HTML will be generated (but the program will carry on).
    """

    from model import PDepReaction
    
    from rmgpy.molecule.draw import MoleculeDrawer
    from rmgpy.chemkin import getSpeciesIdentifier

    try:
        import jinja2
    except ImportError:
        logging.warning("jinja package not found; HTML output will not be saved.")
        return

    path = os.path.abspath(path)
    dirname = os.path.dirname(path)

    # Prepare parameters to pass to jinja template
    title = 'RMG Output'

    species = reactionModel.core.species[:] + reactionModel.outputSpeciesList

    re_index = re.compile(r'\((\d+)\)$')

    if not os.path.isdir(os.path.join(dirname,'species')):
        os.makedirs(os.path.join(dirname,'species'))
    for spec in species:
        # if the species dictionary came from an RMG-Java job, make them prettier
        # We use the presence of a trailing index on the label to discern this
        # (A single open parenthesis is not enough (e.g. when using SMILES strings as labels!)
        match = re_index.search(spec.label)
        if match:
            spec.index = int(match.group(0)[1:-1])
            spec.label = spec.label[0:match.start()]
        # Draw molecules if necessary
        fstr = os.path.join(dirname, 'species', '{0}.png'.format(spec))
        if not os.path.exists(fstr):
            try:
                MoleculeDrawer().draw(spec.molecule[0], 'png', fstr)
            except:
                raise OutputError("{0} species could not be drawn because it did not contain a molecular structure. Please recheck your files.".format(getSpeciesIdentifier(spec)))
                
    # We want to keep species sorted in the original order in which they were added to the RMG core.
    # Rather than ordered by index
#    species.sort(key=lambda x: x.index)

    reactions = [rxn for rxn in reactionModel.core.reactions ] + reactionModel.outputReactionList

    # We want to keep reactions sorted in original order in which they were added to core
    # rather than ordered by index
    #reactions.sort(key=lambda x: x.index)

    familyCount = {}
    for rxn in reactions:
        
        if isinstance(rxn, PDepReaction):
            family = "PDepNetwork"
        else:
            family = rxn.getSource().label
        if family in familyCount:
            familyCount[family] += 1
        else:
            familyCount[family] = 1
    families = familyCount.keys()
    families.sort()
    
    
    ## jinja2 filters etc.
    to_remove_from_css_names = re.compile('[/.\-+,]')
    def csssafe(input):
        "Replace unsafe CSS class name characters with an underscore."
        return to_remove_from_css_names.sub('_',input)
        
    environment = jinja2.Environment()
    environment.filters['csssafe'] = csssafe
    
    # Make HTML file
    template = environment.from_string(
"""<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
    <title>{{ title }}</title>
    <style type="text/css">
        body {
            font-family: sans-serif;
        }
        a {
            color: #993333;
            text-decoration: none;
        }
        a:visited {
            color: #993333;
        }
        a:hover {
            text-decoration: underline;
        }
        table.speciesList, table.reactionList {
            width: 100%;
            border-collapse: collapse;
        }
        table.speciesList th, table.reactionList th {
            text-align: left;
        }
        tr.reaction td {
            border-top: 1px solid #808080;
        }
        td.reactants {
            text-align: right;
        }
        td.products {
            text-align: left;
        }
        td.reactionArrow {
            text-align: center;
            font-size: 16px;
        }
        td.species img, td.reactants img, td.products img {
            vertical-align: middle;
        }
        tr.comment {
            font-size: small;
        }
        tr.kinetics {
            font-size: small;
        }
        .KineticsData {
            # border: 1px solid gray;
        }
        .KineticsData th {
            width: 15em;
            word-wrap: none;
        }
        .KineticsData td {
            width: 3em;
        }
        
        .chemkin, .KineticsData_repr {
           white-space: pre-wrap;
           font-size: x-small;
           font-family: "Andale Mono", monospace;
        }
        
        .hide_comment .comment{
            display: none !important;
        }
        .hide_kinetics .kinetics{
           display: none !important;
        }
        .hide_chemkin .chemkin{
           display: none !important;
        }
    </style>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.1/jquery.min.js"></script>
    <script type="text/javascript" src="../../../external/jquery.min.js"></script>
    <script type="text/javascript">
    function updateFamily(family) {
        if (family.checked) {
            $("."+family.value).show();
        } else {
            $("."+family.value).hide();
        }
    }
    function updateDetails(type) {
        if (type.checked) {
            $(".reactionList").removeClass("hide_"+type.value);
        } else {
            $(".reactionList").addClass("hide_"+type.value);
        }
    }
    function checkAllFamilies() {
        $("#familySelector").find("[name='family']").each(function() { this.checked = true; updateFamily(this); });
        return false;
    }
    function uncheckAllFamilies() {
        $("#familySelector").find("[name='family']").each(function() { this.checked = false; updateFamily(this); });
        return false;
    }
    function checkAllDetails() {
        $("#familySelector").find("[name='detail']").each(function() { this.checked = true; updateDetails(this); });
        return false;
    }
    function uncheckAllDetails() {
        $("#familySelector").find("[name='detail']").each(function() { this.checked = false; updateDetails(this); });
        return false;
    }
    $(document).ready(function() {
        checkAllFamilies();
        uncheckAllDetails();
    });

    </script>
</head>

<body>

<h1>{{ title }}</h1>

<h2>Species ({{ species|length }})</h2>

<table class="speciesList">
    <tr><th>Index</th><th>Structure</th><th>Label</th><th>Mol. Wt. (g/mol)</th></tr>
    {% for spec in species %}
    <tr class="species">
        <td class="index">
        {{ spec.index }}.</td>
        
        
        
        <td class="structure"><a href={{ spec.molecule[0].getURL() }}><img src="species/{{ spec|replace('#','%23') }}.png" alt="{{ spec }}" title="{{ spec }}"></a></td>
        <td class="label">{{ spec.label }}</td>
        <td>{{ "%.2f"|format(spec.molecule[0].getMolecularWeight() * 1000) }}</td>
    </tr>
    {% if spec.thermo %}
    
    <tr>
     <td>
            <table align="center">
                <tr>
                    <th>H298</th>
                    <th>S298</th>
                    <th>Cp300</th>
                    <th>Cp500</th>
                    <th>Cp1000</th>
                    <th>Cp1500</th>
                </tr>
                <tr>
                    <td>
                    {% if spec.thermo.Tmin.value_si <= 298 %}                    
                    {{ "%.2f"|format(spec.thermo.getEnthalpy(298) / 4184) }}
                    {% endif %} </td>
                    <td>{% if spec.thermo.Tmin.value_si <= 298 %}
                    {{ "%.2f"|format(spec.thermo.getEntropy(298) / 4.184) }}
                    {% endif %}</td>
                    <td>{{ "%.2f"|format(spec.thermo.getHeatCapacity(300) / 4.184) }}</td>
                    <td>{{ "%.2f"|format(spec.thermo.getHeatCapacity(500) / 4.184) }}</td>
                    <td>{{ "%.2f"|format(spec.thermo.getHeatCapacity(1000) / 4.184) }}</td>
                    <td>{{ "%.2f"|format(spec.thermo.getHeatCapacity(1500) / 4.184) }}</td>
                </tr>
            </table>
        </td></tr>
        
        {% endif %}
    {% endfor %}
</table>

<h2>Reactions ({{ reactions|length }})</h2>

<form id='familySelector' action="">
    <h4>Reaction families:</h4>
{% for family in families %}    <input type="checkbox" id="{{ family|csssafe }}" name="family" value="{{ family|csssafe }}" checked="checked" onclick="updateFamily(this);"><label for="{{ family|csssafe }}">{{ family }} ({{ familyCount[family] }} rxn{{ 's' if familyCount[family] != 1 }})</label><br>
{% endfor %}
    <a href="javascript:checkAllFamilies();" onclick="checkAllFamilies()">check all</a> &nbsp; &nbsp; <a href="javascript:uncheckAllFamilies();" onclick="uncheckAllFamilies();">uncheck all</a><br>

    <h4>Reaction Details:</h4>
    <input type="checkbox" id="kinetics" name="detail" value="kinetics" onclick="updateDetails(this);"><label for="kinetics">Kinetics</label><br>
    <input type="checkbox" id="comment" name="detail" value="comment" onclick="updateDetails(this);"><label for="comment">Comments</label><br>
    <input type="checkbox" id="chemkin" name="detail" value="chemkin" onclick="updateDetails(this);"><label for="chemkin">Chemkin strings</label><br>
    <a href="javascript:checkAllDetails();" onclick="checkAllDetails()">check all</a> &nbsp; &nbsp; <a href="javascript:uncheckAllDetails();" onclick="uncheckAllDetails();">uncheck all</a>
</form>

<h4>Reaction List:</h4>

<table class="reactionList hide_comment hide_kinetics hide_chemkin">
    <tr><th>Index</th><th colspan="3" style="text-align: center;">Reaction</th><th>Family</th></tr>
    {% for rxn in reactions %}
    <tr class="reaction {{ rxn.getSource().label|csssafe }}">
        <td class="index"><a href="{{ rxn.getURL() }}" title="Search on RMG website" class="searchlink">{{ rxn.index }}.</a></td>
        <td class="reactants">{% for reactant in rxn.reactants %}<a href="{{ reactant.molecule[0].getURL() }}"><img src="species/{{ reactant|replace('#','%23') }}.png" alt="{{ reactant }}" title="{{ reactant }}, MW = {{ "%.2f g/mol"|format(reactant.molecule[0].getMolecularWeight() * 1000) }}"></a>{% if not loop.last %} + {% endif %}{% endfor %}</td>
        <td class="reactionArrow">{% if rxn.reversible %}&hArr;{% else %}&rarr;{% endif %}</td>
        <td class="products">{% for product in rxn.products %}<a href="{{ product.molecule[0].getURL() }}"><img src="species/{{ product|replace('#','%23') }}.png" alt="{{ product }}" title="{{ product }}, MW = {{ "%.2f g/mol"|format(product.molecule[0].getMolecularWeight() * 1000) }}"></a>{% if not loop.last %} + {% endif %}{% endfor %}</td>
        <td class="family">{{ rxn.getSource().label }}</td>
    </tr>
    <tr class="kinetics {{ rxn.getSource().label|csssafe }}">
        <td></td>
        <td colspan="4">{{ rxn.kinetics.toHTML() }}</td>
    </tr>
    <tr class="chemkin {{ rxn.getSource().label|csssafe }}">
        <td></td>
        <td colspan="4">{{ rxn.toChemkin(species) }}</td>
    </tr>
    <tr class="comment {{ rxn.getSource().label|csssafe }}">
        <td></td>
        <td colspan="4">{{ rxn.kinetics.comment }}</td>
    </tr>
    {% endfor %}

</table>

</body>

</html>
""")
    f = open(path, 'w')
    f.write(template.render(title=title, species=species, reactions=reactions, families=families, familyCount=familyCount))
    f.close()
예제 #31
0
#generate species images
mech_path = path + '/data/' + mech
speciesPath = mech_path + '/species/'
if not os.path.isdir(speciesPath):
    os.makedirs(speciesPath)

species = species_list[:]
re_index_search = re.compile(r'\((\d+)\)$').search
for spec in species:
    match = re_index_search(spec.label)
    if match:
        spec.index = int(match.group(0)[1:-1])
        spec.label = spec.label[0:match.start()]
    # Draw molecules if necessary
    fstr = os.path.join(mech_path, 'species', '{0}.png'.format(spec))
    if not os.path.exists(fstr):
        try:
            MoleculeDrawer().draw(spec.molecule[0], 'png', fstr)
        except IndexError:
            raise OutputError("{0} species could not be drawn!".format(
                getSpeciesIdentifier(spec)))

species_target = 'C=CC[CH]CCCCCCC'
# search the target species in model
mol_tgt = Molecule().fromSMILES(species_target)

for spc in species_list:
    if spc.isIsomorphic(mol_tgt):
        print '{} is found in model with spc name {}'.format(
            mol_tgt, getSpeciesIdentifier(spc))
        break