示例#1
0
def chem_scheme_SMILES_extr(sch_name, xml_name, chem_scheme_markers):

    # inputs: ------------------------------------------
    # sch_name - path to chemical scheme
    # xml_name - path to xml name
    # chem_scheme_markers - markers for chemical scheme
    # ----------------------------------------------------

    # initiate with empty error message
    err_mess = ''

    f_open_eqn = open(sch_name, mode='r')  # open the chemical scheme file
    # read the file and store everything into a list
    total_list_eqn = f_open_eqn.readlines()
    f_open_eqn.close()  # close file

    # interrogate scheme to list equations
    [eqn_list, aqeqn_list, eqn_num, rrc, rrc_name,
     RO2_names] = sch_interr.sch_interr(total_list_eqn, chem_scheme_markers)

    # interrogate xml to list all component names and SMILES
    [comp_smil, comp_name] = xml_interr.xml_interr(xml_name)

    comp_namelist = [
    ]  # list for chemical scheme names of components in the chemical scheme
    comp_list = [
    ]  # list for the SMILE strings of components present in the chemical scheme

    for eqn_step in range(eqn_num[0]):  # loop through gas-phase reactions

        line = eqn_list[eqn_step]  # extract this line

        # work out whether equation or reaction rate coefficient part comes first
        eqn_start = str('.*\\' + chem_scheme_markers[10])
        rrc_start = str('.*\\' + chem_scheme_markers[9])
        # get index of these markers, note span is the property of the match object that
        # gives the location of the marker
        eqn_start_indx = (re.match(eqn_start, line)).span()[1]
        rrc_start_indx = (re.match(rrc_start, line)).span()[1]

        if (eqn_start_indx > rrc_start_indx):
            eqn_sec = 1  # equation is second part
        else:
            eqn_sec = 0  # equation is first part

        # split the line into 2 parts: equation and rate coefficient
        # . means match with anything except a new line character., when followed by a *
        # means match zero or more times (so now we match with all characters in the line
        # except for new line characters, so final part is stating the character(s) we
        # are specifically looking for, \\ ensures the marker is recognised
        if eqn_sec == 1:
            eqn_markers = str('\\' + chem_scheme_markers[10] + '.*\\' +
                              chem_scheme_markers[11])
        else:  # end of equation part is start of reaction rate coefficient part
            eqn_markers = str('\\' + chem_scheme_markers[10] + '.*\\' +
                              chem_scheme_markers[9])

        # extract the equation as a string ([0] extracts the equation section and
        # [1:-1] removes the bounding markers)
        eqn = re.findall(eqn_markers, line)[0][1:-1].strip()

        eqn_split = eqn.split()
        eqmark_pos = eqn_split.index('=')
        # reactants with stoichiometry number and omit any photon
        reactants = [
            i for i in eqn_split[:eqmark_pos] if i != '+' and i != 'hv'
        ]
        # products with stoichiometry number
        products = [t for t in eqn_split[eqmark_pos + 1:] if t != '+']

        stoich_regex = r"^\d*\.\d*|^\d*"  # necessary for checking for stoichiometries

        for reactant in reactants:  # left hand side of equations (losses)

            if (re.findall(stoich_regex, reactant)[0] !=
                    ''):  # when stoichiometry included
                # name with no stoichiometry number
                name_only = re.sub(stoich_regex, '', reactant)
            elif (re.findall(
                    stoich_regex,
                    reactant)[0] == ''):  # when stoichiometry excluded
                name_only = reactant

            if (name_only
                    not in comp_namelist):  # if new component encountered

                comp_namelist.append(
                    name_only)  # add to chemical scheme name list

                # convert MCM chemical names to SMILES
                if (name_only in comp_name):
                    # index where xml file name matches reaction component name
                    name_indx = comp_name.index(name_only)
                    name_SMILE = comp_smil[name_indx]  # SMILES of component
                    comp_list.append(name_SMILE)  # list SMILE names
                else:
                    err_mess = str('Error - chemical scheme name ' +
                                   str(name_only) + ' not found in xml file')
                    return (comp_namelist, comp_list, err_mess, H2Oi)

        for product in products:  # right hand side of equations (gains)

            if (re.findall(stoich_regex, product)[0] !=
                    ''):  # when stoichiometry included
                # name with no stoichiometry number
                name_only = re.sub(stoich_regex, '', product)
            elif (re.findall(stoich_regex,
                             product)[0] == ''):  # when stoichiometry excluded
                name_only = product

            if (name_only
                    not in comp_namelist):  # if new component encountered

                comp_namelist.append(
                    name_only)  # add to chemical scheme name list

                # convert MCM chemical names to SMILES
                # index where xml file name matches reaction component name
                if name_only in comp_name:
                    name_indx = comp_name.index(name_only)
                    name_SMILE = comp_smil[name_indx]
                    comp_list.append(name_SMILE)  # list SMILE names
                else:
                    err_mess = str('Error - chemical scheme name ' +
                                   str(name_only) + ' not found in xml file')
                    return (comp_namelist, comp_list, err_mess, H2Oi)

    # check for water presence in chemical scheme via its SMILE string
    # count on components
    indx = -1
    for single_chem in comp_list:
        indx += 1
        # ensure this is water rather than single oxygen (e.g. due to ozone photolysis
        # (O is the MCM chemical scheme name for single oxygen))
        if (single_chem == 'O' and comp_namelist[indx] != 'O'):
            H2Oi = indx

    else:  # if not in chemical scheme, water would be the next component appended to component list
        H2Oi = len(comp_list)
        comp_namelist.append('H2O')

    return (comp_namelist, comp_list, err_mess, H2Oi)
示例#2
0
def extr_mech(sch_name, chem_sch_mrk, xml_name, photo_path, con_infl_nam,
              int_tol, wall_on, num_sb, const_comp, drh_str, erh_str):

    # inputs: ----------------------------------------------------
    # sch_name - file name of chemical scheme
    # chem_sch_mrk - markers to identify different sections of
    # 			the chemical scheme
    # xml_name - name of xml file
    # photo_path - path to file containing absorption
    # 	cross-sections and quantum yields
    # con_infl_nam - chemical scheme names of components with
    # 		constant influx
    # int_tol - integration tolerances
    # wall_on - marker for whether to include wall partitioning
    # num_sb - number of size bins (including any wall)
    # const_comp - chemical scheme name of components with
    #	constant concentration
    # drh_str - string from user inputs describing
    #	deliquescence RH (fraction 0-1) as function of temperature (K)
    # erh_str - string from user inputs describing
    #	efflorescence RH (fraction 0-1) as function of temperature (K)
    # ------------------------------------------------------------

    f_open_eqn = open(sch_name, mode='r')  # open the chemical scheme file
    # read the file and store everything into a list
    total_list_eqn = f_open_eqn.readlines()
    f_open_eqn.close()  # close file

    # interrogate scheme to list equations
    [eqn_list, aqeqn_list, eqn_num, rrc, rrc_name,
     RO2_names] = sch_interr.sch_interr(total_list_eqn, chem_sch_mrk)

    # interrogate xml to list all component names and SMILES
    [comp_smil, comp_name] = xml_interr.xml_interr(xml_name)

    # get equation information for chemical reactions
    [
        rindx_g, rstoi_g, pindx_g, pstoi_g, reac_coef_g, nreac_g, nprod_g,
        jac_stoi_g, jac_den_indx_g, njac_g, jac_indx_g, y_arr_g, y_rind_g,
        uni_y_rind_g, y_pind_g, uni_y_pind_g, reac_col_g, prod_col_g,
        rstoi_flat_g, pstoi_flat_g, rr_arr_g, rr_arr_p_g, rindx_aq, rstoi_aq,
        pindx_aq, pstoi_aq, reac_coef_aq, nreac_aq, nprod_aq, jac_stoi_aq,
        jac_den_indx_aq, njac_aq, jac_indx_aq, y_arr_aq, y_rind_aq,
        uni_y_rind_aq, y_pind_aq, uni_y_pind_aq, reac_col_aq, prod_col_aq,
        rstoi_flat_aq, pstoi_flat_aq, rr_arr_aq, rr_arr_p_aq, comp_namelist,
        comp_list, Pybel_objects, comp_num
    ] = eqn_interr.eqn_interr(eqn_num, eqn_list, aqeqn_list, chem_sch_mrk,
                              comp_name, comp_smil, num_sb, wall_on)

    [rowvals, colptrs, jac_indx_g, jac_indx_aq, jac_part_indx, jac_wall_indx
     ] = jac_setup.jac_setup(jac_den_indx_g, njac_g, comp_num, num_sb, eqn_num,
                             nreac_g, nprod_g, rindx_g, pindx_g, jac_indx_g,
                             wall_on, nreac_aq, nprod_aq, rindx_aq, pindx_aq,
                             jac_indx_aq, (num_sb - wall_on))

    # prepare aqueous-phase reaction matrices for applying to reaction rate calculation
    if (eqn_num[1] > 0):  # if aqueous-phase reactions present
        [
            rindx_aq, rstoi_aq, pindx_aq, pstoi_aq, reac_coef_aq, nprod_aq,
            jac_stoi_aq, njac_aq, jac_den_indx_aq, jac_indx_aq, y_arr_aq,
            y_rind_aq, uni_y_rind_aq, y_pind_aq, uni_y_pind_aq, reac_col_aq,
            prod_col_aq, rstoi_flat_aq, pstoi_flat_aq, rr_arr_aq, rr_arr_p_aq
        ] = aq_mat_prep.aq_mat_prep(
            rindx_aq, rstoi_aq, pindx_aq, pstoi_aq, reac_coef_aq, nprod_aq,
            jac_stoi_aq, njac_aq, jac_den_indx_aq, jac_indx_aq, y_arr_aq,
            y_rind_aq, uni_y_rind_aq, y_pind_aq, uni_y_pind_aq, reac_col_aq,
            prod_col_aq, rstoi_flat_aq, pstoi_flat_aq, rr_arr_aq, rr_arr_p_aq,
            num_sb, wall_on, eqn_num[1], comp_num)

    # get index of components with constant influx/concentration -----------
    # empty array for storing index of components with constant influx
    con_infl_indx = np.zeros((len(con_infl_nam)))
    con_C_indx = np.zeros((len(const_comp)))
    for i in range(len(con_infl_nam)):
        # index of where constant components occur in list of components
        con_infl_indx[i] = comp_namelist.index(con_infl_nam[i])

    for i in range(len(const_comp)):
        # index of where constant concnetration components occur in list
        # of components
        con_C_indx[i] = comp_namelist.index(const_comp[i])
    # ---------------------------------------------------------------------

    # call function to generate ordinary differential equation (ODE)
    # solver module, add two to comp_num to account for water and core component
    write_ode_solv.ode_gen(con_infl_indx, int_tol, rowvals, wall_on,
                           comp_num + 2, (num_sb - wall_on), con_C_indx, 0,
                           eqn_num)

    # call function to generate reaction rate calculation module
    write_rate_file.write_rate_file(reac_coef_g, reac_coef_aq, rrc, rrc_name,
                                    0)

    # call function to generate module that tracks change tendencies
    # of certain components
    write_dydt_rec.write_dydt_rec()

    # write the module for estimating deliquescence and efflorescence
    # relative humidities as a function of temperature
    write_hyst_eq.write_hyst_eq(drh_str, erh_str)

    # get index of components in the peroxy radical list
    RO2_indx = RO2_indices.RO2_indices(comp_namelist, RO2_names)

    # get number of photolysis equations
    Jlen = photo_num.photo_num(photo_path)

    return (rindx_g, pindx_g, rstoi_g, pstoi_g, nreac_g, nprod_g, jac_stoi_g,
            njac_g, jac_den_indx_g, jac_indx_g, y_arr_g, y_rind_g,
            uni_y_rind_g, y_pind_g, uni_y_pind_g, reac_col_g, prod_col_g,
            rstoi_flat_g, pstoi_flat_g, rr_arr_g, rr_arr_p_g, rowvals, colptrs,
            jac_wall_indx, jac_part_indx, comp_num, RO2_indx, comp_list,
            Pybel_objects, eqn_num, comp_namelist, Jlen, rindx_aq, rstoi_aq,
            pindx_aq, pstoi_aq, reac_coef_aq, nreac_aq, nprod_aq, jac_stoi_aq,
            jac_den_indx_aq, njac_aq, jac_indx_aq, y_arr_aq, y_rind_aq,
            uni_y_rind_aq, y_pind_aq, uni_y_pind_aq, reac_col_aq, prod_col_aq,
            rstoi_flat_aq, pstoi_flat_aq, rr_arr_aq, rr_arr_p_aq, comp_name,
            comp_smil)
示例#3
0
except: # when calling from GMD paper Results folder
	output_by_sim = str(cwd + '/fig07_data/Gaswall_sens_Cw0_kw1e2')
	# required outputs
	(num_sb, num_comp, Cfac, y, Ndry, rbou_rec, xfm, t_array, comp_names, 
		y_mw, N, _, y_MV, _, wall_on, space_mode) = retr_out.retr_out(output_by_sim)


# required outputs from full-moving
(num_sb, num_comp, Cfac, y, Ndry, rbou_rec, xfm, t_array, comp_names, 
		y_mw, N, _, y_MV, _, wall_on, space_mode) = retr_out.retr_out(output_by_sim)

# get all SMILE strings from the xml file
# interrogate xml to list component names and SMILES
try: # when calling from the PyCHAM home directory
	[comp_smil, comp_name] = xml_interr.xml_interr(str(cwd + '/PyCHAM/input/example_xml.xml'))
except: # when calling from the GMD paper Results folder
	[comp_smil, comp_name] = xml_interr.xml_interr(str(cwd + '/example_xml.xml'))

# convert chemical scheme component names into SMILEs
comp_smiles = [] # holder
for name in comp_names[0:-2]: # omit H20 and core at end of comp_names
	comp_smiles.append(comp_smil[comp_name.index(name)])

SOA0 = 0.
for i in range(1, num_sb):
	# calculate SOA (*1.0E-12 to convert from g/cc (air) to ug/m3 (air))
	SOA0 += (((y[:, num_comp*i:num_comp*(i+1)-2]/si.N_A)*y_mw[0:-2]*1.0e12).sum(axis=1))

Pybel_objects = [] # holder for Pybel object names
for i in range(num_comp-2): # component loop
示例#4
0
def extr_mech(sch_name, chem_sch_mrk, xml_name, photo_path, con_infl_nam,
              int_tol, wall_on, num_sb, const_comp, drh_str, erh_str, dil_fac,
              sav_nam, pcont):

    # inputs: ----------------------------------------------------
    # sch_name - file name of chemical scheme
    # chem_sch_mrk - markers to identify different sections of
    # 	the chemical scheme
    # xml_name - name of xml file
    # photo_path - path to file containing absorption
    # 	cross-sections and quantum yields
    # con_infl_nam - chemical scheme names of components with
    # 		constant influx
    # int_tol - integration tolerances
    # wall_on - marker for whether to include wall partitioning
    # num_sb - number of size bins (including any wall)
    # const_comp - chemical scheme name of components with
    #	constant concentration
    # drh_str - string from user inputs describing
    #	deliquescence RH (fraction 0-1) as function of temperature (K)
    # erh_str - string from user inputs describing
    #	efflorescence RH (fraction 0-1) as function of temperature (K)
    # dil_fac - fraction of chamber air extracted/s
    # sav_nam - name of folder to save results to
    # pcont - flag for whether seed particle injection is
    #	instantaneous (0) or continuous (1)
    # ------------------------------------------------------------

    # starting error flag and message (assumes no errors)
    erf = 0
    err_mess = ''

    f_open_eqn = open(sch_name, mode='r')  # open the chemical scheme file
    # read the file and store everything into a list
    total_list_eqn = f_open_eqn.readlines()
    f_open_eqn.close()  # close file

    # interrogate scheme to list equations
    [eqn_list, aqeqn_list, eqn_num, rrc, rrc_name,
     RO2_names] = sch_interr.sch_interr(total_list_eqn, chem_sch_mrk)

    # interrogate xml to list all component names and SMILES
    [comp_smil, comp_name] = xml_interr.xml_interr(xml_name)

    # get equation information for chemical reactions
    [
        rindx_g, rstoi_g, pindx_g, pstoi_g, reac_coef_g, nreac_g, nprod_g,
        jac_stoi_g, jac_den_indx_g, njac_g, jac_indx_g, y_arr_g, y_rind_g,
        uni_y_rind_g, y_pind_g, uni_y_pind_g, reac_col_g, prod_col_g,
        rstoi_flat_g, pstoi_flat_g, rr_arr_g, rr_arr_p_g, rindx_aq, rstoi_aq,
        pindx_aq, pstoi_aq, reac_coef_aq, nreac_aq, nprod_aq, jac_stoi_aq,
        jac_den_indx_aq, njac_aq, jac_indx_aq, y_arr_aq, y_rind_aq,
        uni_y_rind_aq, y_pind_aq, uni_y_pind_aq, reac_col_aq, prod_col_aq,
        rstoi_flat_aq, pstoi_flat_aq, rr_arr_aq, rr_arr_p_aq, comp_namelist,
        comp_list, Pybel_objects, comp_num, RO_indx
    ] = eqn_interr.eqn_interr(eqn_num, eqn_list, aqeqn_list, chem_sch_mrk,
                              comp_name, comp_smil, num_sb, wall_on)

    [
        rowvals, colptrs, jac_indx_g, jac_indx_aq, jac_part_indx,
        jac_wall_indx, jac_extr_indx
    ] = jac_setup.jac_setup(jac_den_indx_g, njac_g, comp_num, num_sb, eqn_num,
                            nreac_g, nprod_g, rindx_g, pindx_g, jac_indx_g,
                            wall_on, nreac_aq, nprod_aq, rindx_aq, pindx_aq,
                            jac_indx_aq, (num_sb - wall_on), dil_fac)

    # prepare aqueous-phase reaction matrices for applying to reaction rate calculation
    if (eqn_num[1] > 0):  # if aqueous-phase reactions present
        [
            rindx_aq, rstoi_aq, pindx_aq, pstoi_aq, reac_coef_aq, nprod_aq,
            jac_stoi_aq, njac_aq, jac_den_indx_aq, jac_indx_aq, y_arr_aq,
            y_rind_aq, uni_y_rind_aq, y_pind_aq, uni_y_pind_aq, reac_col_aq,
            prod_col_aq, rstoi_flat_aq, pstoi_flat_aq, rr_arr_aq, rr_arr_p_aq
        ] = aq_mat_prep.aq_mat_prep(
            rindx_aq, rstoi_aq, pindx_aq, pstoi_aq, reac_coef_aq, nprod_aq,
            jac_stoi_aq, njac_aq, jac_den_indx_aq, jac_indx_aq, y_arr_aq,
            y_rind_aq, uni_y_rind_aq, y_pind_aq, uni_y_pind_aq, reac_col_aq,
            prod_col_aq, rstoi_flat_aq, pstoi_flat_aq, rr_arr_aq, rr_arr_p_aq,
            num_sb, wall_on, eqn_num[1], comp_num)

    # get index of components with constant influx/concentration -----------
    # empty array for storing index of components with constant influx
    con_infl_indx = np.zeros((len(con_infl_nam)))
    con_C_indx = np.zeros((len(const_comp))).astype('int')
    for i in range(len(con_infl_nam)):
        # water not included explicitly in chemical schemes but accounted for later in init_conc
        if (con_infl_nam[i] == 'H2O'):
            con_infl_indx[i] = comp_num
            continue
        try:
            # index of where components with constant influx occur in list of components
            con_infl_indx[i] = comp_namelist.index(con_infl_nam[i])
        except:
            erf = 1  # raise error
            err_mess = str(
                'Error: constant influx component with name ' +
                str(con_infl_nam[i]) +
                ' has not been identified in the chemical scheme, please check it is present and the chemical scheme markers are correct'
            )

    for i in range(len(const_comp)):
        try:
            # index of where constant concentration components occur in list
            # of components
            con_C_indx[i] = comp_namelist.index(const_comp[i])
        except:
            erf = 1  # raise error
            err_mess = str(
                'Error: constant concentration component with name ' +
                str(const_comp[i]) +
                ' has not been identified in the chemical scheme, please check it is present and the chemical scheme markers are correct'
            )

    # ---------------------------------------------------------------------

    # call function to generate ordinary differential equation (ODE)
    # solver module, add two to comp_num to account for water and core component
    write_ode_solv.ode_gen(con_infl_indx, int_tol, rowvals, wall_on,
                           comp_num + 2, (num_sb - wall_on), 0, eqn_num,
                           dil_fac, sav_nam, pcont)

    # call function to generate reaction rate calculation module
    write_rate_file.write_rate_file(reac_coef_g, reac_coef_aq, rrc, rrc_name,
                                    0)

    # call function to generate module that tracks change tendencies
    # of certain components
    write_dydt_rec.write_dydt_rec()

    # write the module for estimating deliquescence and efflorescence
    # relative humidities as a function of temperature
    write_hyst_eq.write_hyst_eq(drh_str, erh_str)

    # get index of components in the peroxy radical list
    RO2_indx = RO2_indices.RO2_indices(comp_namelist, RO2_names)

    # get index of HOM-RO2 radicals
    HOMRO2_indx = RO2_indices.HOMRO2_indices(comp_namelist)

    # get number of photolysis equations
    Jlen = photo_num.photo_num(photo_path)

    return (rindx_g, pindx_g, rstoi_g, pstoi_g, nreac_g, nprod_g, jac_stoi_g,
            njac_g, jac_den_indx_g, jac_indx_g, y_arr_g, y_rind_g,
            uni_y_rind_g, y_pind_g, uni_y_pind_g, reac_col_g, prod_col_g,
            rstoi_flat_g, pstoi_flat_g, rr_arr_g, rr_arr_p_g, rowvals, colptrs,
            jac_wall_indx, jac_part_indx, jac_extr_indx, comp_num, RO2_indx,
            RO_indx, HOMRO2_indx, comp_list, Pybel_objects, eqn_num,
            comp_namelist, Jlen, rindx_aq, rstoi_aq, pindx_aq, pstoi_aq,
            reac_coef_aq, nreac_aq, nprod_aq, jac_stoi_aq, jac_den_indx_aq,
            njac_aq, jac_indx_aq, y_arr_aq, y_rind_aq, uni_y_rind_aq,
            y_pind_aq, uni_y_pind_aq, reac_col_aq, prod_col_aq, rstoi_flat_aq,
            pstoi_flat_aq, rr_arr_aq, rr_arr_p_aq, comp_name, comp_smil, erf,
            err_mess, con_C_indx)