Skip to content

SIEM Reference

Here is the detailed information of SIEM classes and functions.

SIEM: SImplified Emission Model.

SIEM produces the emission file required to run WRF-Chem and CMAQ air quality models.

This modules defined the classes used by siem to create this emissions files
  • EmissionSource - Class to spatially and temporal distribute emissions, especially vehicular emissions.
  • PointSources - Class to spatially and temporal distribute point sources from a .csv table.
  • GroupSources - Class to group EmissionSources and PointSources, useful to create one emission file.

EmissionSource

Emission source.

A class used to represent and emission source to be estimated from spatial proxy.

Attributes:

Name Type Description
name

Name of Source.

number

Number of Sources.

use_intensity

Use intensity

pol_ef

Pollutant emission factors and molecular weight.

spatial_proxy

Spatial proxy to spatial distribute emissions.

temporal_prof

Temporal profile to temporal distribute emissions.

voc_spc

VOC species to speciate with their fraction.

pm_spc

PM species to speciate with their fraction.

Source code in siem/siem.py
class EmissionSource:
    """Emission source.

    A class used to represent and emission source to
    be estimated from spatial proxy.

    Attributes:
        name: Name of Source.
        number: Number of Sources.
        use_intensity: Use intensity
        pol_ef: Pollutant emission factors and molecular weight.
        spatial_proxy: Spatial proxy to spatial distribute emissions.
        temporal_prof: Temporal profile to temporal distribute emissions.
        voc_spc: VOC species to speciate with their fraction.
        pm_spc: PM species to speciate with their fraction.
    """

    def __init__(
        self,
        name: str,
        number: int | float,
        use_intensity: float,
        pol_ef: dict,
        spatial_proxy: xr.DataArray,
        temporal_prof: list[float],
        voc_spc: dict,
        pm_spc: dict,
    ):
        """Create the EmissionSource object.

        Args:
            name: Name of the source.
            number: Number of sources (e.g., number of vehicles)
            use_intensity: Emission source activity rate.
            pol_ef: Keys are pollutants in the inventory.
                Values are a tuple with pollutant emission factors and molecular weight.
            spatial_proxy: Proxy to spatially distribute emissions.
            temporal_prof: Hourly fractions to temporally distribute emissions.
            voc_spc: Keys are VOC species.Values are the fraction of the total VOC.
            pm_spc: Keys are PM species. Values are the fraction of the total PM.
        """
        self.name = name
        self.number = number
        self.use_intensity = use_intensity
        self.pol_ef = pol_ef
        self.spatial_proxy = spatial_proxy
        self.temporal_prof = temporal_prof
        self.voc_spc = voc_spc
        self.pm_spc = pm_spc

    def __str__(self):
        """Print summary of EmissionSource attributes.

        Returns:
            Print name, number, pollutants,
            and VOC and PM species information
            from EmissionSource.
        """
        source_summary = (
            f"Source name: {self.name}\n"
            f"Number: {self.number}\n"
            f"Pollutants: {list(self.pol_ef.keys())}\n"
            f"Number VOC species: {len(self.voc_spc.keys())}\n"
            f"Number PM species: {len(self.pm_spc.keys())}\n"
        )
        return source_summary

    def total_emission(self, pol_name: str, ktn_year: bool = False) -> float:
        """Calculate total emission of a pollutant.

        Args:
            pol_name: Pollutant name to calculate the total emission.
            ktn_year: If total is calculated in KTn (Gg) year^-1

        Returns:
            Total emission of a pollutant.
        """
        total_emiss = em.calculate_emission(
            self.number, self.use_intensity, self.pol_ef[pol_name][0]
        )
        # units of total_emiss in g day^-1

        if ktn_year:
            return total_emiss * 365 / 10**9
        return total_emiss

    def report_emissions(self) -> pd.DataFrame:
        """Return the total emission for each pollutant in pol_ef.

        Returns:
            A table with pollutants as index and total emissions
            as columns.
        """
        total_emission = {
            pol: self.total_emission(pol, ktn_year=True) for pol in self.pol_ef.keys()
        }
        total_emission = pd.DataFrame.from_dict(
            total_emission, orient="index", columns=["total_emiss"]
        )
        return total_emission

    def spatial_emission(self, pol_name: str, cell_area: int | float) -> xr.DataArray:
        """Distribute one pollutant.

        Args:
            pol_name: Key value in pol_ef.
            cell_area: Area of wrfinput.

        Returns:
            Spatially distributed emissions.
        """
        return spt.distribute_spatial_emission(
            self.spatial_proxy,
            self.number,
            cell_area,
            self.use_intensity,
            self.pol_ef[pol_name][0],
            pol_name,
        )

    def spatiotemporal_emission(
        self, pol_names: str | list[str], cell_area: int | float, is_cmaq: bool = False
    ) -> xr.DataArray:
        """Spatial and temporal distribution of emissions.

        Args:
            pol_names: Name or names of pollutants to distribute.
            cell_area: Wrfinput cell area.
            is_cmaq: If it will be used for CMAQ.

        Returns:
            Spatial and temporal emission distribution.
        """
        if isinstance(pol_names, str):
            pol_names = [pol_names]

        spatial_emissions = {
            pol: self.spatial_emission(pol, cell_area) for pol in pol_names
        }

        temp_prof = self.temporal_prof
        if is_cmaq:
            temp_prof = cmaq.to_25hr_profile(self.temporal_prof)

        spatio_temporal = {
            pol: temp.split_by_time(spatial, temp_prof)
            for pol, spatial in spatial_emissions.items()
        }
        return xr.merge(spatio_temporal.values())

    def speciate_emission(
        self,
        pol_name: str,
        pol_species: dict,
        cell_area: int | float,
        is_cmaq: bool = False,
    ) -> xr.DataArray:
        """Speciate one pollutant emissions. Used especially for VOC or NOX.

        Args:
            pol_name: Pollutant name in pol_ef to speciate.
            pol_species: Keys are pollutants speciated from pol_name.
                Values are the fraction.
            cell_area: wrfinput cell area km^2
            is_cmaq: If output is for CMAQ.

        Returns:
            Spatial and temporal distribution of speciated emission.
        """
        spatio_temporal = self.spatiotemporal_emission(pol_name, cell_area, is_cmaq)
        speciated_emiss = em.speciate_emission(
            spatio_temporal, pol_name, pol_species, cell_area
        )
        return speciated_emiss

    def speciate_all(
        self,
        cell_area: int | float,
        voc_name: str = "VOC",
        pm_name: str = "PM",
        is_cmaq: bool = False,
    ) -> xr.Dataset:
        """Speciate VOC and PM.

        Args:
            cell_area: wrfinput cell area.
            voc_name: Name of VOC in pol_ef keys.
            pm_name: Name of PM in pol_ef keys.
            is_cmaq: If output for CMAQ.

        Returns:
            Spatial and temporal distributed emissions with
            VOC and PM speciated.
        """
        spatio_temporal = self.spatiotemporal_emission(
            self.pol_ef.keys(), cell_area, is_cmaq
        )
        speciated_emiss = em.speciate_emission(
            spatio_temporal, voc_name, self.voc_spc, cell_area
        )
        speciated_emiss = em.speciate_emission(
            speciated_emiss, pm_name, self.pm_spc, cell_area
        )
        return speciated_emiss

    def to_wrfchemi(
        self,
        wrfinput: xr.Dataset,
        start_date: str,
        end_date: str,
        week_profile: list[float] = [1],
        pm_name: str = "PM",
        voc_name: str = "VOC",
        write_netcdf: bool = False,
        nc_format: str = "NETCDF3_64BIT",
        path: str = "../results",
    ) -> xr.Dataset:
        """Create WRF-Chem emission file (wrfchemi).

        Args:
            wrfinput: WRF-Chem wrfinput file.
            start_date: Start date of emissions.
            end_date: End date of emissions.
            week_profile: List of seven fraction of each week day.
            pm_name: PM name in pol_ef keys.
            voc_name: VOC name in pol_ef keys
            write_netcdf: Write the NetCDF file.
            nc_format: wrfchemi NetCDF file format.
            path: Location to save wrfchemi.

        Returns:
            Dataset with wrfchemi netCDF format.
        """
        cell_area = (wrfinput.DX / 1000) ** 2
        spatio_temporal = self.spatiotemporal_emission(self.pol_ef.keys(), cell_area)
        if len(week_profile) == 7:
            spatio_temporal = temp.split_by_weekday(
                spatio_temporal, week_profile, start_date, end_date
            )
        spatio_temporal = wemi.transform_wrfchemi_units(
            spatio_temporal, self.pol_ef, pm_name
        )
        speciated_emiss = wemi.speciate_wrfchemi(
            spatio_temporal,
            self.voc_spc,
            self.pm_spc,
            cell_area,
            wrfinput,
            voc_name,
            pm_name,
        )
        wrfchemi_netcdf = wemi.prepare_wrfchemi_netcdf(
            speciated_emiss, wrfinput, start_date
        )

        if write_netcdf:
            wemi.write_wrfchemi_netcdf(wrfchemi_netcdf, nc_format, path)
        return wrfchemi_netcdf

    def to_cmaq(
        self,
        wrfinput: xr.Dataset,
        griddesc_path: str,
        btrim: int,
        start_date: str,
        end_date: str,
        week_profile: list[float] = [1],
        pm_name: str = "PM",
        voc_name: str = "VOC",
        write_netcdf: bool = False,
        path: str = "../results",
    ) -> typing.Dict[str, xr.Dataset]:
        """Create CMAQ emission file.

        Args:
            wrfinput: wrfinput from WRF simulation.
            griddesc_path: Location of GRIDDESC file.
            btrim: BTRIM option in MCIP.
            start_date: Start date of emission files.
            end_date: End date of emission files.
            week_profile: List of seven fraction of each week day.
            pm_name: PM name in pol_ef keys.
            voc_name: VOC name in pol_ef keys.
            write_netcdf: Write the netCDF file.
            path: Location to save CMAQ emission file.

        Returns:
            Keys are simulation days and values the emission file for CMAQ
            for that day.
        """
        cell_area = (wrfinput.DX / 1000) ** 2
        spatio_temporal = self.spatiotemporal_emission(
            self.pol_ef.keys(), cell_area, is_cmaq=True
        )
        spatio_temporal_units = cmaq.transform_cmaq_units(
            spatio_temporal, self.pol_ef, cell_area
        )
        speciated_emiss = cmaq.speciate_cmaq(
            spatio_temporal_units, self.voc_spc, self.pm_spc, cell_area
        )

        # TODO: Change it to a function
        for emi in speciated_emiss.data_vars:
            speciated_emiss[emi] = speciated_emiss[emi].astype("float32")

        days_factor = temp.assign_factor_simulation_days(
            start_date, end_date, week_profile, is_cmaq=True
        )
        cmaq_files = {
            day: cmaq.prepare_netcdf_cmaq(
                speciated_emiss * fact,
                day,
                griddesc_path,
                btrim,
                self.voc_spc,
                self.pm_spc,
            )
            for day, fact in zip(days_factor.day, days_factor.frac)
        }
        if write_netcdf:
            for cmaq_nc in cmaq_files.values():
                cmaq.save_cmaq_file(cmaq_nc, path)
        return cmaq_files

__init__(name, number, use_intensity, pol_ef, spatial_proxy, temporal_prof, voc_spc, pm_spc)

Create the EmissionSource object.

Parameters:

Name Type Description Default
name str

Name of the source.

required
number int | float

Number of sources (e.g., number of vehicles)

required
use_intensity float

Emission source activity rate.

required
pol_ef dict

Keys are pollutants in the inventory. Values are a tuple with pollutant emission factors and molecular weight.

required
spatial_proxy DataArray

Proxy to spatially distribute emissions.

required
temporal_prof list[float]

Hourly fractions to temporally distribute emissions.

required
voc_spc dict

Keys are VOC species.Values are the fraction of the total VOC.

required
pm_spc dict

Keys are PM species. Values are the fraction of the total PM.

required
Source code in siem/siem.py
def __init__(
    self,
    name: str,
    number: int | float,
    use_intensity: float,
    pol_ef: dict,
    spatial_proxy: xr.DataArray,
    temporal_prof: list[float],
    voc_spc: dict,
    pm_spc: dict,
):
    """Create the EmissionSource object.

    Args:
        name: Name of the source.
        number: Number of sources (e.g., number of vehicles)
        use_intensity: Emission source activity rate.
        pol_ef: Keys are pollutants in the inventory.
            Values are a tuple with pollutant emission factors and molecular weight.
        spatial_proxy: Proxy to spatially distribute emissions.
        temporal_prof: Hourly fractions to temporally distribute emissions.
        voc_spc: Keys are VOC species.Values are the fraction of the total VOC.
        pm_spc: Keys are PM species. Values are the fraction of the total PM.
    """
    self.name = name
    self.number = number
    self.use_intensity = use_intensity
    self.pol_ef = pol_ef
    self.spatial_proxy = spatial_proxy
    self.temporal_prof = temporal_prof
    self.voc_spc = voc_spc
    self.pm_spc = pm_spc

__str__()

Print summary of EmissionSource attributes.

Returns:

Type Description

Print name, number, pollutants,

and VOC and PM species information

from EmissionSource.

Source code in siem/siem.py
def __str__(self):
    """Print summary of EmissionSource attributes.

    Returns:
        Print name, number, pollutants,
        and VOC and PM species information
        from EmissionSource.
    """
    source_summary = (
        f"Source name: {self.name}\n"
        f"Number: {self.number}\n"
        f"Pollutants: {list(self.pol_ef.keys())}\n"
        f"Number VOC species: {len(self.voc_spc.keys())}\n"
        f"Number PM species: {len(self.pm_spc.keys())}\n"
    )
    return source_summary

report_emissions()

Return the total emission for each pollutant in pol_ef.

Returns:

Type Description
DataFrame

A table with pollutants as index and total emissions

DataFrame

as columns.

Source code in siem/siem.py
def report_emissions(self) -> pd.DataFrame:
    """Return the total emission for each pollutant in pol_ef.

    Returns:
        A table with pollutants as index and total emissions
        as columns.
    """
    total_emission = {
        pol: self.total_emission(pol, ktn_year=True) for pol in self.pol_ef.keys()
    }
    total_emission = pd.DataFrame.from_dict(
        total_emission, orient="index", columns=["total_emiss"]
    )
    return total_emission

spatial_emission(pol_name, cell_area)

Distribute one pollutant.

Parameters:

Name Type Description Default
pol_name str

Key value in pol_ef.

required
cell_area int | float

Area of wrfinput.

required

Returns:

Type Description
DataArray

Spatially distributed emissions.

Source code in siem/siem.py
def spatial_emission(self, pol_name: str, cell_area: int | float) -> xr.DataArray:
    """Distribute one pollutant.

    Args:
        pol_name: Key value in pol_ef.
        cell_area: Area of wrfinput.

    Returns:
        Spatially distributed emissions.
    """
    return spt.distribute_spatial_emission(
        self.spatial_proxy,
        self.number,
        cell_area,
        self.use_intensity,
        self.pol_ef[pol_name][0],
        pol_name,
    )

spatiotemporal_emission(pol_names, cell_area, is_cmaq=False)

Spatial and temporal distribution of emissions.

Parameters:

Name Type Description Default
pol_names str | list[str]

Name or names of pollutants to distribute.

required
cell_area int | float

Wrfinput cell area.

required
is_cmaq bool

If it will be used for CMAQ.

False

Returns:

Type Description
DataArray

Spatial and temporal emission distribution.

Source code in siem/siem.py
def spatiotemporal_emission(
    self, pol_names: str | list[str], cell_area: int | float, is_cmaq: bool = False
) -> xr.DataArray:
    """Spatial and temporal distribution of emissions.

    Args:
        pol_names: Name or names of pollutants to distribute.
        cell_area: Wrfinput cell area.
        is_cmaq: If it will be used for CMAQ.

    Returns:
        Spatial and temporal emission distribution.
    """
    if isinstance(pol_names, str):
        pol_names = [pol_names]

    spatial_emissions = {
        pol: self.spatial_emission(pol, cell_area) for pol in pol_names
    }

    temp_prof = self.temporal_prof
    if is_cmaq:
        temp_prof = cmaq.to_25hr_profile(self.temporal_prof)

    spatio_temporal = {
        pol: temp.split_by_time(spatial, temp_prof)
        for pol, spatial in spatial_emissions.items()
    }
    return xr.merge(spatio_temporal.values())

speciate_all(cell_area, voc_name='VOC', pm_name='PM', is_cmaq=False)

Speciate VOC and PM.

Parameters:

Name Type Description Default
cell_area int | float

wrfinput cell area.

required
voc_name str

Name of VOC in pol_ef keys.

'VOC'
pm_name str

Name of PM in pol_ef keys.

'PM'
is_cmaq bool

If output for CMAQ.

False

Returns:

Type Description
Dataset

Spatial and temporal distributed emissions with

Dataset

VOC and PM speciated.

Source code in siem/siem.py
def speciate_all(
    self,
    cell_area: int | float,
    voc_name: str = "VOC",
    pm_name: str = "PM",
    is_cmaq: bool = False,
) -> xr.Dataset:
    """Speciate VOC and PM.

    Args:
        cell_area: wrfinput cell area.
        voc_name: Name of VOC in pol_ef keys.
        pm_name: Name of PM in pol_ef keys.
        is_cmaq: If output for CMAQ.

    Returns:
        Spatial and temporal distributed emissions with
        VOC and PM speciated.
    """
    spatio_temporal = self.spatiotemporal_emission(
        self.pol_ef.keys(), cell_area, is_cmaq
    )
    speciated_emiss = em.speciate_emission(
        spatio_temporal, voc_name, self.voc_spc, cell_area
    )
    speciated_emiss = em.speciate_emission(
        speciated_emiss, pm_name, self.pm_spc, cell_area
    )
    return speciated_emiss

speciate_emission(pol_name, pol_species, cell_area, is_cmaq=False)

Speciate one pollutant emissions. Used especially for VOC or NOX.

Parameters:

Name Type Description Default
pol_name str

Pollutant name in pol_ef to speciate.

required
pol_species dict

Keys are pollutants speciated from pol_name. Values are the fraction.

required
cell_area int | float

wrfinput cell area km^2

required
is_cmaq bool

If output is for CMAQ.

False

Returns:

Type Description
DataArray

Spatial and temporal distribution of speciated emission.

Source code in siem/siem.py
def speciate_emission(
    self,
    pol_name: str,
    pol_species: dict,
    cell_area: int | float,
    is_cmaq: bool = False,
) -> xr.DataArray:
    """Speciate one pollutant emissions. Used especially for VOC or NOX.

    Args:
        pol_name: Pollutant name in pol_ef to speciate.
        pol_species: Keys are pollutants speciated from pol_name.
            Values are the fraction.
        cell_area: wrfinput cell area km^2
        is_cmaq: If output is for CMAQ.

    Returns:
        Spatial and temporal distribution of speciated emission.
    """
    spatio_temporal = self.spatiotemporal_emission(pol_name, cell_area, is_cmaq)
    speciated_emiss = em.speciate_emission(
        spatio_temporal, pol_name, pol_species, cell_area
    )
    return speciated_emiss

to_cmaq(wrfinput, griddesc_path, btrim, start_date, end_date, week_profile=[1], pm_name='PM', voc_name='VOC', write_netcdf=False, path='../results')

Create CMAQ emission file.

Parameters:

Name Type Description Default
wrfinput Dataset

wrfinput from WRF simulation.

required
griddesc_path str

Location of GRIDDESC file.

required
btrim int

BTRIM option in MCIP.

required
start_date str

Start date of emission files.

required
end_date str

End date of emission files.

required
week_profile list[float]

List of seven fraction of each week day.

[1]
pm_name str

PM name in pol_ef keys.

'PM'
voc_name str

VOC name in pol_ef keys.

'VOC'
write_netcdf bool

Write the netCDF file.

False
path str

Location to save CMAQ emission file.

'../results'

Returns:

Type Description
Dict[str, Dataset]

Keys are simulation days and values the emission file for CMAQ

Dict[str, Dataset]

for that day.

Source code in siem/siem.py
def to_cmaq(
    self,
    wrfinput: xr.Dataset,
    griddesc_path: str,
    btrim: int,
    start_date: str,
    end_date: str,
    week_profile: list[float] = [1],
    pm_name: str = "PM",
    voc_name: str = "VOC",
    write_netcdf: bool = False,
    path: str = "../results",
) -> typing.Dict[str, xr.Dataset]:
    """Create CMAQ emission file.

    Args:
        wrfinput: wrfinput from WRF simulation.
        griddesc_path: Location of GRIDDESC file.
        btrim: BTRIM option in MCIP.
        start_date: Start date of emission files.
        end_date: End date of emission files.
        week_profile: List of seven fraction of each week day.
        pm_name: PM name in pol_ef keys.
        voc_name: VOC name in pol_ef keys.
        write_netcdf: Write the netCDF file.
        path: Location to save CMAQ emission file.

    Returns:
        Keys are simulation days and values the emission file for CMAQ
        for that day.
    """
    cell_area = (wrfinput.DX / 1000) ** 2
    spatio_temporal = self.spatiotemporal_emission(
        self.pol_ef.keys(), cell_area, is_cmaq=True
    )
    spatio_temporal_units = cmaq.transform_cmaq_units(
        spatio_temporal, self.pol_ef, cell_area
    )
    speciated_emiss = cmaq.speciate_cmaq(
        spatio_temporal_units, self.voc_spc, self.pm_spc, cell_area
    )

    # TODO: Change it to a function
    for emi in speciated_emiss.data_vars:
        speciated_emiss[emi] = speciated_emiss[emi].astype("float32")

    days_factor = temp.assign_factor_simulation_days(
        start_date, end_date, week_profile, is_cmaq=True
    )
    cmaq_files = {
        day: cmaq.prepare_netcdf_cmaq(
            speciated_emiss * fact,
            day,
            griddesc_path,
            btrim,
            self.voc_spc,
            self.pm_spc,
        )
        for day, fact in zip(days_factor.day, days_factor.frac)
    }
    if write_netcdf:
        for cmaq_nc in cmaq_files.values():
            cmaq.save_cmaq_file(cmaq_nc, path)
    return cmaq_files

to_wrfchemi(wrfinput, start_date, end_date, week_profile=[1], pm_name='PM', voc_name='VOC', write_netcdf=False, nc_format='NETCDF3_64BIT', path='../results')

Create WRF-Chem emission file (wrfchemi).

Parameters:

Name Type Description Default
wrfinput Dataset

WRF-Chem wrfinput file.

required
start_date str

Start date of emissions.

required
end_date str

End date of emissions.

required
week_profile list[float]

List of seven fraction of each week day.

[1]
pm_name str

PM name in pol_ef keys.

'PM'
voc_name str

VOC name in pol_ef keys

'VOC'
write_netcdf bool

Write the NetCDF file.

False
nc_format str

wrfchemi NetCDF file format.

'NETCDF3_64BIT'
path str

Location to save wrfchemi.

'../results'

Returns:

Type Description
Dataset

Dataset with wrfchemi netCDF format.

Source code in siem/siem.py
def to_wrfchemi(
    self,
    wrfinput: xr.Dataset,
    start_date: str,
    end_date: str,
    week_profile: list[float] = [1],
    pm_name: str = "PM",
    voc_name: str = "VOC",
    write_netcdf: bool = False,
    nc_format: str = "NETCDF3_64BIT",
    path: str = "../results",
) -> xr.Dataset:
    """Create WRF-Chem emission file (wrfchemi).

    Args:
        wrfinput: WRF-Chem wrfinput file.
        start_date: Start date of emissions.
        end_date: End date of emissions.
        week_profile: List of seven fraction of each week day.
        pm_name: PM name in pol_ef keys.
        voc_name: VOC name in pol_ef keys
        write_netcdf: Write the NetCDF file.
        nc_format: wrfchemi NetCDF file format.
        path: Location to save wrfchemi.

    Returns:
        Dataset with wrfchemi netCDF format.
    """
    cell_area = (wrfinput.DX / 1000) ** 2
    spatio_temporal = self.spatiotemporal_emission(self.pol_ef.keys(), cell_area)
    if len(week_profile) == 7:
        spatio_temporal = temp.split_by_weekday(
            spatio_temporal, week_profile, start_date, end_date
        )
    spatio_temporal = wemi.transform_wrfchemi_units(
        spatio_temporal, self.pol_ef, pm_name
    )
    speciated_emiss = wemi.speciate_wrfchemi(
        spatio_temporal,
        self.voc_spc,
        self.pm_spc,
        cell_area,
        wrfinput,
        voc_name,
        pm_name,
    )
    wrfchemi_netcdf = wemi.prepare_wrfchemi_netcdf(
        speciated_emiss, wrfinput, start_date
    )

    if write_netcdf:
        wemi.write_wrfchemi_netcdf(wrfchemi_netcdf, nc_format, path)
    return wrfchemi_netcdf

total_emission(pol_name, ktn_year=False)

Calculate total emission of a pollutant.

Parameters:

Name Type Description Default
pol_name str

Pollutant name to calculate the total emission.

required
ktn_year bool

If total is calculated in KTn (Gg) year^-1

False

Returns:

Type Description
float

Total emission of a pollutant.

Source code in siem/siem.py
def total_emission(self, pol_name: str, ktn_year: bool = False) -> float:
    """Calculate total emission of a pollutant.

    Args:
        pol_name: Pollutant name to calculate the total emission.
        ktn_year: If total is calculated in KTn (Gg) year^-1

    Returns:
        Total emission of a pollutant.
    """
    total_emiss = em.calculate_emission(
        self.number, self.use_intensity, self.pol_ef[pol_name][0]
    )
    # units of total_emiss in g day^-1

    if ktn_year:
        return total_emiss * 365 / 10**9
    return total_emiss

GroupSources

A class that group EmissionSources and PointSources object.

Attributes sources_list: A list of EmissionSources and PointSources objects.

Source code in siem/siem.py
class GroupSources:
    """A class that group EmissionSources and PointSources object.

    Attributes
        sources_list: A list of EmissionSources and PointSources objects.
    """

    def __init__(self, sources_list: list[EmissionSource | PointSources]):
        """Create a GroupSource object.

        Args:
            sources_list: List with EmissionSource and PointSources to group.
        """
        self.sources = {source.name: source for source in sources_list}

    def __str__(self):
        """Print summary of GroupSources attributes.

        Returns:
            Print number and types of Sources.
        """
        type_of_sources = [type(source) for source in self.sources.values()]
        source_summary = (
            f"Number of sources: {len(self.names())}\n"
            f"Type of sources: {set(type_of_sources)}\n"
        )
        return source_summary

    def names(self):
        """Print names of source emission in GroupSources.

        Returns:
            Names of source emissions.
        """
        names = list(self.sources.keys())
        return names

    def report_emissions(self) -> pd.DataFrame:
        """Return the total emission for each pollutant in pol_emiss.

        Returns:
            Table with emission source and pollutant as index.
        """
        total_emissions = {
            src_name: src.report_emissions() for src_name, src in self.sources.items()
        }
        return pd.concat(total_emissions, names=["src", "pol"])

    def to_wrfchemi(
        self,
        wrfinput: xr.Dataset,
        start_date: str,
        end_date: str,
        week_profile: list[float] = [1],
        pm_name: str = "PM",
        voc_name: str = "VOC",
        write_netcdf: bool = False,
        nc_format: str = "NETCDF3_64BIT",
        path: str = "../results",
    ) -> xr.Dataset:
        """Create WRF-Chem emission file.

        Args:
            wrfinput: WRF-Chem wrfinput.
            start_date: Start date of emission.
            end_date: End date of emission.
            week_profile: Emission weights of days of week.
            pm_name: PM name in emissions.
            voc_name: VOC name in emissions.
            write_netcdf: Save wrfchemi file.
            nc_format: wrfchemi NetCDF file.
            path: Location to save wrfchemi file.

        Returns:
            Emission file in WRF-Chem wrfchemi netCDF format.
        """
        wrfchemis = {
            source: emiss.to_wrfchemi(
                wrfinput,
                start_date,
                end_date,
                week_profile,
                pm_name,
                voc_name,
                write_netcdf=False,
            )
            for source, emiss in self.sources.items()
        }
        wrfchemi = xr.concat(
            wrfchemis.values(), pd.Index(wrfchemis.keys(), name="source")
        )
        if write_netcdf:
            wrfchemi = wrfchemi.sum(dim="source", keep_attrs=True)
            wrfchemi["Times"] = xr.DataArray(
                wemi.create_date_s19(f"{start_date}_00:00:00", wrfchemi.sizes["Time"]),
                dims=["Time"],
                coords={"Time": wrfchemi.Time.values},
            )
            wemi.write_wrfchemi_netcdf(wrfchemi, nc_format, path=path)
        return wrfchemi

    def to_cmaq(
        self,
        wrfinput: xr.Dataset,
        griddesc_path: str,
        btrim: int,
        start_date: str,
        end_date: str,
        week_profile: list[float] = [1],
        pm_name: str = "PM",
        voc_name: str = "VOC",
        write_netcdf: bool = False,
        path: str = "../results",
    ) -> typing.Dict[str, dict]:
        """Create CMAQ emission file.

        Create CMAQ emission file. All EmissionSource and GroupSources
        need to have same speciation.

        Args:
            wrfinput: WRF wrfinput file.
            griddesc_path: Location of GRIDDESC file.
            btrim: BTRIM value in MCIP.
            start_date: Start date of emissions.
            end_date: End date of emissions.
            week_profile: Emission weights of days of week.
            pm_name: PM name in pol_ef or pol_emiss.
            voc_name: VOC name in pol_ef or pol_emiss.
            write_netcdf: Save CMAQ emission file.
            path: Location to save CMAQ emission file.

        Returns::
            Keys are emission days. Values are emission in CMAQ
            emission file netCDF format.
        """
        cmaq_files = {
            source: emiss.to_cmaq(
                wrfinput,
                griddesc_path,
                btrim,
                start_date,
                end_date,
                week_profile,
                pm_name,
                voc_name,
            )
            for source, emiss in self.sources.items()
        }
        cmaq_source_day = cmaq.merge_cmaq_source_emiss(cmaq_files)
        sum_sources = cmaq.sum_cmaq_sources(cmaq_source_day)
        cmaq_sum_by_day = cmaq.update_tflag_sources(sum_sources)

        if write_netcdf:
            for cmaq_nc in cmaq_sum_by_day.values():
                cmaq.save_cmaq_file(cmaq_nc, path)
        return cmaq_sum_by_day

__init__(sources_list)

Create a GroupSource object.

Parameters:

Name Type Description Default
sources_list list[EmissionSource | PointSources]

List with EmissionSource and PointSources to group.

required
Source code in siem/siem.py
def __init__(self, sources_list: list[EmissionSource | PointSources]):
    """Create a GroupSource object.

    Args:
        sources_list: List with EmissionSource and PointSources to group.
    """
    self.sources = {source.name: source for source in sources_list}

__str__()

Print summary of GroupSources attributes.

Returns:

Type Description

Print number and types of Sources.

Source code in siem/siem.py
def __str__(self):
    """Print summary of GroupSources attributes.

    Returns:
        Print number and types of Sources.
    """
    type_of_sources = [type(source) for source in self.sources.values()]
    source_summary = (
        f"Number of sources: {len(self.names())}\n"
        f"Type of sources: {set(type_of_sources)}\n"
    )
    return source_summary

names()

Print names of source emission in GroupSources.

Returns:

Type Description

Names of source emissions.

Source code in siem/siem.py
def names(self):
    """Print names of source emission in GroupSources.

    Returns:
        Names of source emissions.
    """
    names = list(self.sources.keys())
    return names

report_emissions()

Return the total emission for each pollutant in pol_emiss.

Returns:

Type Description
DataFrame

Table with emission source and pollutant as index.

Source code in siem/siem.py
def report_emissions(self) -> pd.DataFrame:
    """Return the total emission for each pollutant in pol_emiss.

    Returns:
        Table with emission source and pollutant as index.
    """
    total_emissions = {
        src_name: src.report_emissions() for src_name, src in self.sources.items()
    }
    return pd.concat(total_emissions, names=["src", "pol"])

to_cmaq(wrfinput, griddesc_path, btrim, start_date, end_date, week_profile=[1], pm_name='PM', voc_name='VOC', write_netcdf=False, path='../results')

Create CMAQ emission file.

Create CMAQ emission file. All EmissionSource and GroupSources need to have same speciation.

Parameters:

Name Type Description Default
wrfinput Dataset

WRF wrfinput file.

required
griddesc_path str

Location of GRIDDESC file.

required
btrim int

BTRIM value in MCIP.

required
start_date str

Start date of emissions.

required
end_date str

End date of emissions.

required
week_profile list[float]

Emission weights of days of week.

[1]
pm_name str

PM name in pol_ef or pol_emiss.

'PM'
voc_name str

VOC name in pol_ef or pol_emiss.

'VOC'
write_netcdf bool

Save CMAQ emission file.

False
path str

Location to save CMAQ emission file.

'../results'

Returns:: Keys are emission days. Values are emission in CMAQ emission file netCDF format.

Source code in siem/siem.py
def to_cmaq(
    self,
    wrfinput: xr.Dataset,
    griddesc_path: str,
    btrim: int,
    start_date: str,
    end_date: str,
    week_profile: list[float] = [1],
    pm_name: str = "PM",
    voc_name: str = "VOC",
    write_netcdf: bool = False,
    path: str = "../results",
) -> typing.Dict[str, dict]:
    """Create CMAQ emission file.

    Create CMAQ emission file. All EmissionSource and GroupSources
    need to have same speciation.

    Args:
        wrfinput: WRF wrfinput file.
        griddesc_path: Location of GRIDDESC file.
        btrim: BTRIM value in MCIP.
        start_date: Start date of emissions.
        end_date: End date of emissions.
        week_profile: Emission weights of days of week.
        pm_name: PM name in pol_ef or pol_emiss.
        voc_name: VOC name in pol_ef or pol_emiss.
        write_netcdf: Save CMAQ emission file.
        path: Location to save CMAQ emission file.

    Returns::
        Keys are emission days. Values are emission in CMAQ
        emission file netCDF format.
    """
    cmaq_files = {
        source: emiss.to_cmaq(
            wrfinput,
            griddesc_path,
            btrim,
            start_date,
            end_date,
            week_profile,
            pm_name,
            voc_name,
        )
        for source, emiss in self.sources.items()
    }
    cmaq_source_day = cmaq.merge_cmaq_source_emiss(cmaq_files)
    sum_sources = cmaq.sum_cmaq_sources(cmaq_source_day)
    cmaq_sum_by_day = cmaq.update_tflag_sources(sum_sources)

    if write_netcdf:
        for cmaq_nc in cmaq_sum_by_day.values():
            cmaq.save_cmaq_file(cmaq_nc, path)
    return cmaq_sum_by_day

to_wrfchemi(wrfinput, start_date, end_date, week_profile=[1], pm_name='PM', voc_name='VOC', write_netcdf=False, nc_format='NETCDF3_64BIT', path='../results')

Create WRF-Chem emission file.

Parameters:

Name Type Description Default
wrfinput Dataset

WRF-Chem wrfinput.

required
start_date str

Start date of emission.

required
end_date str

End date of emission.

required
week_profile list[float]

Emission weights of days of week.

[1]
pm_name str

PM name in emissions.

'PM'
voc_name str

VOC name in emissions.

'VOC'
write_netcdf bool

Save wrfchemi file.

False
nc_format str

wrfchemi NetCDF file.

'NETCDF3_64BIT'
path str

Location to save wrfchemi file.

'../results'

Returns:

Type Description
Dataset

Emission file in WRF-Chem wrfchemi netCDF format.

Source code in siem/siem.py
def to_wrfchemi(
    self,
    wrfinput: xr.Dataset,
    start_date: str,
    end_date: str,
    week_profile: list[float] = [1],
    pm_name: str = "PM",
    voc_name: str = "VOC",
    write_netcdf: bool = False,
    nc_format: str = "NETCDF3_64BIT",
    path: str = "../results",
) -> xr.Dataset:
    """Create WRF-Chem emission file.

    Args:
        wrfinput: WRF-Chem wrfinput.
        start_date: Start date of emission.
        end_date: End date of emission.
        week_profile: Emission weights of days of week.
        pm_name: PM name in emissions.
        voc_name: VOC name in emissions.
        write_netcdf: Save wrfchemi file.
        nc_format: wrfchemi NetCDF file.
        path: Location to save wrfchemi file.

    Returns:
        Emission file in WRF-Chem wrfchemi netCDF format.
    """
    wrfchemis = {
        source: emiss.to_wrfchemi(
            wrfinput,
            start_date,
            end_date,
            week_profile,
            pm_name,
            voc_name,
            write_netcdf=False,
        )
        for source, emiss in self.sources.items()
    }
    wrfchemi = xr.concat(
        wrfchemis.values(), pd.Index(wrfchemis.keys(), name="source")
    )
    if write_netcdf:
        wrfchemi = wrfchemi.sum(dim="source", keep_attrs=True)
        wrfchemi["Times"] = xr.DataArray(
            wemi.create_date_s19(f"{start_date}_00:00:00", wrfchemi.sizes["Time"]),
            dims=["Time"],
            coords={"Time": wrfchemi.Time.values},
        )
        wemi.write_wrfchemi_netcdf(wrfchemi, nc_format, path=path)
    return wrfchemi

PointSources

Point sources.

A class to read points emission sources in a table where columns are longitude, latitude, and the total emissions of diferent pollutants in kTn (Gg) year^-1

Attributes name : Name of the point emission sources. spatial_emission : Spatially distributed emissions in simulation domain. pol_emiss : Names of considered pollutants (columns). temporal_prof : Temporal profile to temporal emission distribution. voc_spc : VOC speciation dict. Keys are VOC species, values are fractions. pm_spc : PM speciation dict. Keys are PM species, values are fractions.

Source code in siem/siem.py
class PointSources:
    """Point sources.

    A class to read points emission sources in a
    table where columns are longitude, latitude, and
    the total emissions of diferent pollutants in
    kTn (Gg) year^-1

    Attributes
        name : Name of the point emission sources.
        spatial_emission : Spatially distributed emissions in simulation domain.
        pol_emiss : Names of considered pollutants (columns).
        temporal_prof : Temporal profile to temporal emission distribution.
        voc_spc : VOC speciation dict. Keys are VOC species, values are fractions.
        pm_spc : PM speciation dict. Keys are PM species, values are fractions.
    """

    def __init__(
        self,
        name: str,
        point_emiss: xr.Dataset,
        pol_emiss: dict,
        temporal_prof: list[float],
        voc_spc: dict,
        pm_spc: dict,
    ):
        """Create PointSource  object.

        Args:
            name: Name of point sources emissions.
            point_emiss: Points sources in table read with
            pol_emiss: Keys are columns in point_emiss.
                Values are the molecular weight.
            temporal_prof: Hourly fractions to temporally distribute emissions.
            voc_spc: Keys are VOC species.
                Values are fractions from the total VOC.
            pm_spc: Keys are PM species. Values are fractions from the total PM.
        """
        self.name = name
        self.spatial_emission = point_emiss
        self.pol_emiss = pol_emiss
        self.temporal_prof = temporal_prof
        self.voc_spc = voc_spc
        self.pm_spc = pm_spc

    def __str__(self):
        """Print summary of PointSource attributes.

        Returns:
            Print name, number, pollutants,
            and VOC and PM species information
            from EmissionSource.
        """
        source_summary = (
            f"Source name: {self.name}\n"
            f"Pollutants: {list(self.pol_emiss.keys())}\n"
            f"Number VOC species: {len(self.voc_spc.keys())}\n"
            f"Number PM species: {len(self.pm_spc.keys())}\n"
        )
        return source_summary

    def total_emission(self, pol_name: str) -> float:
        """Calculate total emission of a pollutant.

        Args:
            pol_name: Pollutant name to calculate the total emission.

        Returns:
            Total emission of a pollutant in KTn (Gg) year^-1
        """
        if pol_name in self.pol_emiss.keys():
            return self.spatial_emission[pol_name].sum().values
        else:
            print(f"{pol_name} not include in data")

    def report_emissions(self) -> pd.DataFrame:
        """Return the total emission for each pollutant in pol_ef.

        Returns:
            A table with pollutants as index and total emissions
            as columns.
        """
        total_emission = {
            pol: self.total_emission(pol) for pol in self.pol_emiss.keys()
        }
        total_emission = pd.DataFrame.from_dict(
            total_emission, orient="index", columns=["total_emiss"]
        )
        return total_emission

    def to_wrfchemi(
        self,
        wrfinput: xr.Dataset,
        start_date: str,
        end_date: str,
        week_profile: list[float] = [1],
        pm_name: str = "PM",
        voc_name: str = "VOC",
        write_netcdf: bool = False,
        nc_format: str = "NETCDF3_64BIT",
        path: str = "../results/",
    ) -> xr.Dataset:
        """Create WRF-Chem emission file.

        Args:
            wrfinput: WRF wrfinput.
            start_date: Start date of emission.
            end_date: End date of emission.
            week_profile: Emission weights of days of week.
            pm_name: PM name in pol_emiss.
            voc_name: VOC name in pol_emiss.
            write_netcdf: Write wrfchemi netCDF.
            nc_format: wrfchemi NetCDF file format.
            path: Location to save wrfchemi files.

        Returns:
            Emission file in wrfchemi netCDF format.
        """
        cell_area = (wrfinput.DX / 1000) ** 2
        point_gd = em.ktn_year_to_g_day(self.spatial_emission)  # g day^-1
        point_gh = temp.split_by_time_from(point_gd, self.temporal_prof)  # g hr^-1
        point_spc_time = wemi.transform_wrfchemi_units_point(
            point_gh, self.pol_emiss, cell_area
        )
        if len(week_profile) == 7:
            point_spc_time = temp.split_by_weekday(
                point_spc_time, week_profile, start_date, end_date
            )
        point_speciated = wemi.speciate_wrfchemi(
            point_spc_time, self.voc_spc, self.pm_spc, cell_area, wrfinput
        )
        wrfchemi_netcdf = wemi.prepare_wrfchemi_netcdf(
            point_speciated, wrfinput, start_date
        )
        if write_netcdf:
            wemi.write_wrfchemi_netcdf(wrfchemi_netcdf, nc_format, path)
        return wrfchemi_netcdf

    def to_cmaq(
        self,
        wrfinput: xr.Dataset,
        griddesc_path: str,
        btrim: int,
        start_date: str,
        end_date: str,
        week_profile: list[float] = [1],
        pm_name: str = "PM",
        voc_name: str = "VOC",
        write_netcdf: bool = False,
        path: str = "../results",
    ) -> typing.Dict[str, xr.Dataset]:
        """Create CMAQ emission file.

        Create and save CMAQ emission file.

        Args:
            wrfinput: WRF wrfinput.
            griddesc_path: Location of GRIDDESC file.
            btrim: BTRIM value in MCIP.
            start_date: Start date of emission.
            end_date: End date of emission.
            week_profile: Emission weights of days of week.
            pm_name: PM name in pol_emiss.
            voc_name: VOC name in pol_emiss.
            write_netcdf: Save CMAQ emission file.
            path: Location to save CMAQ emission file.
        Returns:
            Keys are simulation day.
            Values are Daset in CMAQ emission file netcdf format.
        """
        cell_area = (wrfinput.DX / 1000) ** 2
        point_gd = em.ktn_year_to_g_day(self.spatial_emission)  # g day^-1
        cmaq_temp_prof = cmaq.to_25hr_profile(self.temporal_prof)
        point_time = temp.split_by_time_from(
            point_gd,  # g hr^-1
            cmaq_temp_prof,
        )

        point_time_units = cmaq.transform_cmaq_units_point(
            point_time, self.pol_emiss, pm_name
        )
        speciated_emiss = cmaq.speciate_cmaq(
            point_time_units, self.voc_spc, self.pm_spc, cell_area
        )
        for emi in speciated_emiss.data_vars:
            speciated_emiss[emi] = speciated_emiss[emi].astype("float32")

        days_factor = temp.assign_factor_simulation_days(
            start_date, end_date, week_profile, is_cmaq=True
        )
        cmaq_files = {
            day: cmaq.prepare_netcdf_cmaq(
                speciated_emiss * fact,
                day,
                griddesc_path,
                btrim,
                self.voc_spc,
                self.pm_spc,
            )
            for day, fact in zip(days_factor.day, days_factor.frac)
        }
        if write_netcdf:
            for cmaq_nc in cmaq_files.values():
                cmaq.save_cmaq_file(cmaq_nc, path)
        return cmaq_files

__init__(name, point_emiss, pol_emiss, temporal_prof, voc_spc, pm_spc)

Create PointSource object.

Parameters:

Name Type Description Default
name str

Name of point sources emissions.

required
point_emiss Dataset

Points sources in table read with

required
pol_emiss dict

Keys are columns in point_emiss. Values are the molecular weight.

required
temporal_prof list[float]

Hourly fractions to temporally distribute emissions.

required
voc_spc dict

Keys are VOC species. Values are fractions from the total VOC.

required
pm_spc dict

Keys are PM species. Values are fractions from the total PM.

required
Source code in siem/siem.py
def __init__(
    self,
    name: str,
    point_emiss: xr.Dataset,
    pol_emiss: dict,
    temporal_prof: list[float],
    voc_spc: dict,
    pm_spc: dict,
):
    """Create PointSource  object.

    Args:
        name: Name of point sources emissions.
        point_emiss: Points sources in table read with
        pol_emiss: Keys are columns in point_emiss.
            Values are the molecular weight.
        temporal_prof: Hourly fractions to temporally distribute emissions.
        voc_spc: Keys are VOC species.
            Values are fractions from the total VOC.
        pm_spc: Keys are PM species. Values are fractions from the total PM.
    """
    self.name = name
    self.spatial_emission = point_emiss
    self.pol_emiss = pol_emiss
    self.temporal_prof = temporal_prof
    self.voc_spc = voc_spc
    self.pm_spc = pm_spc

__str__()

Print summary of PointSource attributes.

Returns:

Type Description

Print name, number, pollutants,

and VOC and PM species information

from EmissionSource.

Source code in siem/siem.py
def __str__(self):
    """Print summary of PointSource attributes.

    Returns:
        Print name, number, pollutants,
        and VOC and PM species information
        from EmissionSource.
    """
    source_summary = (
        f"Source name: {self.name}\n"
        f"Pollutants: {list(self.pol_emiss.keys())}\n"
        f"Number VOC species: {len(self.voc_spc.keys())}\n"
        f"Number PM species: {len(self.pm_spc.keys())}\n"
    )
    return source_summary

report_emissions()

Return the total emission for each pollutant in pol_ef.

Returns:

Type Description
DataFrame

A table with pollutants as index and total emissions

DataFrame

as columns.

Source code in siem/siem.py
def report_emissions(self) -> pd.DataFrame:
    """Return the total emission for each pollutant in pol_ef.

    Returns:
        A table with pollutants as index and total emissions
        as columns.
    """
    total_emission = {
        pol: self.total_emission(pol) for pol in self.pol_emiss.keys()
    }
    total_emission = pd.DataFrame.from_dict(
        total_emission, orient="index", columns=["total_emiss"]
    )
    return total_emission

to_cmaq(wrfinput, griddesc_path, btrim, start_date, end_date, week_profile=[1], pm_name='PM', voc_name='VOC', write_netcdf=False, path='../results')

Create CMAQ emission file.

Create and save CMAQ emission file.

Parameters:

Name Type Description Default
wrfinput Dataset

WRF wrfinput.

required
griddesc_path str

Location of GRIDDESC file.

required
btrim int

BTRIM value in MCIP.

required
start_date str

Start date of emission.

required
end_date str

End date of emission.

required
week_profile list[float]

Emission weights of days of week.

[1]
pm_name str

PM name in pol_emiss.

'PM'
voc_name str

VOC name in pol_emiss.

'VOC'
write_netcdf bool

Save CMAQ emission file.

False
path str

Location to save CMAQ emission file.

'../results'

Returns: Keys are simulation day. Values are Daset in CMAQ emission file netcdf format.

Source code in siem/siem.py
def to_cmaq(
    self,
    wrfinput: xr.Dataset,
    griddesc_path: str,
    btrim: int,
    start_date: str,
    end_date: str,
    week_profile: list[float] = [1],
    pm_name: str = "PM",
    voc_name: str = "VOC",
    write_netcdf: bool = False,
    path: str = "../results",
) -> typing.Dict[str, xr.Dataset]:
    """Create CMAQ emission file.

    Create and save CMAQ emission file.

    Args:
        wrfinput: WRF wrfinput.
        griddesc_path: Location of GRIDDESC file.
        btrim: BTRIM value in MCIP.
        start_date: Start date of emission.
        end_date: End date of emission.
        week_profile: Emission weights of days of week.
        pm_name: PM name in pol_emiss.
        voc_name: VOC name in pol_emiss.
        write_netcdf: Save CMAQ emission file.
        path: Location to save CMAQ emission file.
    Returns:
        Keys are simulation day.
        Values are Daset in CMAQ emission file netcdf format.
    """
    cell_area = (wrfinput.DX / 1000) ** 2
    point_gd = em.ktn_year_to_g_day(self.spatial_emission)  # g day^-1
    cmaq_temp_prof = cmaq.to_25hr_profile(self.temporal_prof)
    point_time = temp.split_by_time_from(
        point_gd,  # g hr^-1
        cmaq_temp_prof,
    )

    point_time_units = cmaq.transform_cmaq_units_point(
        point_time, self.pol_emiss, pm_name
    )
    speciated_emiss = cmaq.speciate_cmaq(
        point_time_units, self.voc_spc, self.pm_spc, cell_area
    )
    for emi in speciated_emiss.data_vars:
        speciated_emiss[emi] = speciated_emiss[emi].astype("float32")

    days_factor = temp.assign_factor_simulation_days(
        start_date, end_date, week_profile, is_cmaq=True
    )
    cmaq_files = {
        day: cmaq.prepare_netcdf_cmaq(
            speciated_emiss * fact,
            day,
            griddesc_path,
            btrim,
            self.voc_spc,
            self.pm_spc,
        )
        for day, fact in zip(days_factor.day, days_factor.frac)
    }
    if write_netcdf:
        for cmaq_nc in cmaq_files.values():
            cmaq.save_cmaq_file(cmaq_nc, path)
    return cmaq_files

to_wrfchemi(wrfinput, start_date, end_date, week_profile=[1], pm_name='PM', voc_name='VOC', write_netcdf=False, nc_format='NETCDF3_64BIT', path='../results/')

Create WRF-Chem emission file.

Parameters:

Name Type Description Default
wrfinput Dataset

WRF wrfinput.

required
start_date str

Start date of emission.

required
end_date str

End date of emission.

required
week_profile list[float]

Emission weights of days of week.

[1]
pm_name str

PM name in pol_emiss.

'PM'
voc_name str

VOC name in pol_emiss.

'VOC'
write_netcdf bool

Write wrfchemi netCDF.

False
nc_format str

wrfchemi NetCDF file format.

'NETCDF3_64BIT'
path str

Location to save wrfchemi files.

'../results/'

Returns:

Type Description
Dataset

Emission file in wrfchemi netCDF format.

Source code in siem/siem.py
def to_wrfchemi(
    self,
    wrfinput: xr.Dataset,
    start_date: str,
    end_date: str,
    week_profile: list[float] = [1],
    pm_name: str = "PM",
    voc_name: str = "VOC",
    write_netcdf: bool = False,
    nc_format: str = "NETCDF3_64BIT",
    path: str = "../results/",
) -> xr.Dataset:
    """Create WRF-Chem emission file.

    Args:
        wrfinput: WRF wrfinput.
        start_date: Start date of emission.
        end_date: End date of emission.
        week_profile: Emission weights of days of week.
        pm_name: PM name in pol_emiss.
        voc_name: VOC name in pol_emiss.
        write_netcdf: Write wrfchemi netCDF.
        nc_format: wrfchemi NetCDF file format.
        path: Location to save wrfchemi files.

    Returns:
        Emission file in wrfchemi netCDF format.
    """
    cell_area = (wrfinput.DX / 1000) ** 2
    point_gd = em.ktn_year_to_g_day(self.spatial_emission)  # g day^-1
    point_gh = temp.split_by_time_from(point_gd, self.temporal_prof)  # g hr^-1
    point_spc_time = wemi.transform_wrfchemi_units_point(
        point_gh, self.pol_emiss, cell_area
    )
    if len(week_profile) == 7:
        point_spc_time = temp.split_by_weekday(
            point_spc_time, week_profile, start_date, end_date
        )
    point_speciated = wemi.speciate_wrfchemi(
        point_spc_time, self.voc_spc, self.pm_spc, cell_area, wrfinput
    )
    wrfchemi_netcdf = wemi.prepare_wrfchemi_netcdf(
        point_speciated, wrfinput, start_date
    )
    if write_netcdf:
        wemi.write_wrfchemi_netcdf(wrfchemi_netcdf, nc_format, path)
    return wrfchemi_netcdf

total_emission(pol_name)

Calculate total emission of a pollutant.

Parameters:

Name Type Description Default
pol_name str

Pollutant name to calculate the total emission.

required

Returns:

Type Description
float

Total emission of a pollutant in KTn (Gg) year^-1

Source code in siem/siem.py
def total_emission(self, pol_name: str) -> float:
    """Calculate total emission of a pollutant.

    Args:
        pol_name: Pollutant name to calculate the total emission.

    Returns:
        Total emission of a pollutant in KTn (Gg) year^-1
    """
    if pol_name in self.pol_emiss.keys():
        return self.spatial_emission[pol_name].sum().values
    else:
        print(f"{pol_name} not include in data")