README

Air Emissions Processor program

AEP is a program designed to ingest data collected during national emissions inventories and process it for use in air quality models by breaking up emissions into detailed chemical groups, spatially allocating the emissions to a grid or other set of shapes, and then temporally allocating the emissions to specific times of the year.

The program is designed to more or less reproduce the functionality of the SMOKE model, but with a focus on usability, flexibility, and expandability. This model differs from the SMOKE model in several ways:

  • AEP is a single self-contained model, rather than a set of executables linked by shell scripts. This makes it much easier to use.
  • AEP can process all of the sectors of a national emissions inventory simultaneously, based on a single configuration file, instead of requiring a custom set of shell scripts for each sector. This makes the program much easier to use and reduces the opportunity for configuration errors.
  • AEP's spatial surrogate generator is integrated into the program and generates surrogates automatically, instead of requiring a completely separate program to generate spatial surrogates. This greatly reduces the time and effort required to produce emissions for a new model domain.
  • In AEP, the spatial domain is set up automatically based on WRF namelist.input and namelist.wps files, and meteorology information for plume rise is read directly from WRF output files from a previous run. This avoids the need for a seperate meteorology preprocesser and a multiple spatial domain configuration files in different formats.
  • AEP extracts chemical speciation information directly from the SPECIATE database, eliminating the need for a separate program to create speciation files and greatly reducing the effort required to change the chemical speciation mechanism used when processing emissions.
  • AEP outputs emissions information directly to the WRF/Chem file format; other file formats can be added.
  • AEP is designed to take advantage of multiprocessor computers, with automatic shared-memory concurrancy.

Installation

  1. Install the Go compiler. Make sure you install the correct version (32 or 64 bit) for your system. It is recommended to install the compiler to the default location; if you experience problems try seeing if they are resolved by installing the compiler to the default location.

  2. Download and install the software library and utilities:

     go get github.com/spatialmodel/inmap/emissions/aep/...
    

    The Go language has an automatic system for finding and installing library dependencies; you may want to refer here to understand how it works.

Use

  1. Obtain the necessary emissions data and ancilliary information. Information for obtaining 2014 US National Emissions Inventory data is available here. In addition to the changes to the data suggested in the README file in that directory, the road shapefile for spatial surrogates is misaligned and emissions from commercial cooking in New York State appear to be unreasonably high.

  2. Process the data. Although AEP is not currently available as an executable program, the full API is described here and a simplified API for common tasks is described here. More extensive documentation is not yet available, but an example of spatially processing annual total emissions is available here.

TODO (Things that SMOKE can do that AEP cannot)
  • Add capability to process meteorology-dependent emissions (e.g., vehicle tailpipe, wood smoke, road dust)

  • Add capability to integrate with the MOVES vehicle emissions model.

Expand ▾ Collapse ▴

Documentation

Index

Constants

View Source
const (
	VOC           SpeciationType = "VOC"
	VOCUngrouped                 = "VOCUngrouped" // Do not group VOCs into a chemical mechanism.
	NOx                          = "NOx"
	PM25                         = "PM2.5"
	SingleSpecies                = "Single" // This pollutant is already speciated.
	Direct                       = "Direct" // The speciation profile is directly specified in the configuration.
)

These are the currently supported speciation types.

View Source
const (
	USA               Country = 0
	Canada                    = 1
	Mexico                    = 2
	Cuba                      = 3
	Bahamas                   = 4
	Haiti                     = 5
	DominicanRepublic         = 6
	Global                    = 7
	Unknown                   = -1
)

These are the currently supported countries.

Variables

This section is empty.

Functions

func EmissionsTotal

func EmissionsTotal(recs []Record) map[Pollutant]*unit.Unit

EmissionsTotal returns the total combined emissions in recs.

func IsStringInArray

func IsStringInArray(a []string, s string) bool

IsStringInArray returns whether s is a member of a.

func MatchCode

func MatchCode(code string, matchmap map[string]interface{}) (matchedCode string, matchVal interface{}, err error)

MatchCode finds code in matchmap. For cases where a specific code needs to be matched with a more general code. For instance, if code is "10101" and matchmap is {"10102":"xxx","10100":"yyyy"}, "10100" will be returned as the closest match to the input code. "10102" will never be returned, even if the "10100" item didn't exist. Returns an error if there is no match.

func MatchCodeDouble

func MatchCodeDouble(code1, code2 string, matchmap map[string]map[string]interface{}) (matchedCode1, matchedCode2 string, matchVal interface{}, err error)

MatchCodeDouble finds code1 and code2 in matchmap.

func NAICSDesc

func NAICSDesc(filename string) (map[string]string, error)

NAICSDesc reads a NAICS description file, which gives descriptions for each NAICS code.

func ReadCOARDSFile

func ReadCOARDSFile(file string, begin, end time.Time, units InputUnits, sourceData SourceData) (func() (Record, error), error)

ReadCOARDSFile reads a COARDS-compliant NetCDF file (NetCDF 4 and greater not supported) and returns a record generator. The generator will return io.EOF after the last record. All floating point variables that have dimensions [lat, lon] are assumed to be emissions variables. begin and end specify the time period when the emissions occur. units represents the input units of the emissions. SourceData specifies additional information to be included in each emissions record. Data in the COARDS file are assumed to be row-major (i.e., latitude-major). Information regarding the COARDS NetCDF conventions are available here: https://ferret.pmel.noaa.gov/Ferret/documentation/coards-netcdf-conventions.

func SCCDescription

func SCCDescription(r io.Reader) (map[string]string, error)

SCCDescription reads a SMOKE sccdesc file, which gives descriptions for each SCC code. The returned data is in the form map[SCC]description.

func SICDesc

func SICDesc(filename string) (map[string]string, error)

SICDesc reads an SIC description file, which gives descriptions for each SIC code.

Types

type ControlData

type ControlData struct {
	// Maximum Available Control Technology Code
	// (6 characters maximum) (optional)
	MACT string

	// Control efficiency percentage (give value of 0-100) (recommended,
	// if left blank, default is 0).
	CEff float64

	// Rule Effectiveness percentage (give value of 0-100) (recommended,
	// if left blank, default is 100)
	REff float64

	// Rule Penetration percentage (give value of 0-100) (optional;
	// if missing will result in default of 100)
	RPen float64
}

ControlData holds information about how emissions from this source can be controlled.

type Country

type Country int

Country represents a country where emissions occur.

func (Country) String

func (c Country) String() string

type EconomicData

type EconomicData struct {
	// SIC is the Standard Industrial Classification Code (recommended)
	SIC string

	// North American Industrial Classification System Code
	// (6 characters maximum) (optional)
	NAICS string
}

EconomicData holds industry information about an emissions source

func (*EconomicData) GetEconomicData

func (r *EconomicData) GetEconomicData() *EconomicData

GetEconomicData returns r.

type Emissions

type Emissions struct {
	// contains filtered or unexported fields
}

Emissions holds information about the rate of emissions from a source of different pollutants and potentially at different times.

func (*Emissions) Add

func (e *Emissions) Add(begin, end time.Time, pollutant, polPrefix string, rate *unit.Unit)

Add adds emissions beginning and ending at times begin and end, respectively, of pollutant 'pollutant' with prefix 'polPrefix' (e.g., BRK, TIR, etc), and of total amount 'amount'. Emissions are expected to be in units of g/s.

func (*Emissions) Clone

func (e *Emissions) Clone() *Emissions

Clone returns a copy of the receiver.

func (*Emissions) CombineEmissions

func (e *Emissions) CombineEmissions(r2 Record)

CombineEmissions combines emissions from r2 into this record.

func (*Emissions) DropPols

func (e *Emissions) DropPols(polsToKeep Speciation) map[Pollutant]*unit.Unit

DropPols removes the pollutants that are not in polsToKeep and returns the total emissions removed, in units of [mass]. If polsToKeep is nil, all pollutants are kept.

func (*Emissions) GetEmissions

func (e *Emissions) GetEmissions() *Emissions

GetEmissions returns the emissions associated with this record

func (*Emissions) PeriodTotals

func (e *Emissions) PeriodTotals(begin, end time.Time) map[Pollutant]*unit.Unit

PeriodTotals returns the total emissions from this emissions source between the times begin and end.

func (*Emissions) Scale

func (e *Emissions) Scale(f func(Pollutant) (float64, error)) error

Scale scales the emissions in the receiver according to f, which is a function that gives emissions multipliers by Pollutant.

func (Emissions) String

func (e Emissions) String() string

func (*Emissions) Totals

func (e *Emissions) Totals() map[Pollutant]*unit.Unit

Totals returns the total emissions in units of [mass].

type EmissionsReader

type EmissionsReader struct {

	// Group specifies a group name for files read by this reader.
	// It is used for report creation
	Group string
	// contains filtered or unexported fields
}

An EmissionsReader reads SMOKE formatted emissions files.

func NewEmissionsReader

func NewEmissionsReader(polsToKeep Speciation, freq InventoryFrequency, InputUnits InputUnits, gr *GridRef, sp *SrgSpecs) (*EmissionsReader, error)

NewEmissionsReader creates a new EmissionsReader. polsToKeep specifies which pollutants from the inventory to keep. If it is nil, all pollutants are kept. InputUnits is the units of input data. Acceptable values are `tons', `tonnes', `kg', `g', and `lbs'. gr and sp are used to reference emissions records to geographic locations; if they are both nil, the location referencing is skipped.

func (*EmissionsReader) OpenFilesFromTemplate

func (e *EmissionsReader) OpenFilesFromTemplate(filetemplate string) ([]*InventoryFile, error)

OpenFilesFromTemplate opens the files that match the template.

func (*EmissionsReader) ReadFiles

func (e *EmissionsReader) ReadFiles(files []*InventoryFile, f RecFilter) ([]Record, *InventoryReport, error)

ReadFiles reads emissions associated with period p from the specified files, and returns emissions records and a summary report. The specified filenames are only used for reporting. If multiple files have data for the same specific facility (for instance, if one file has CAPs emissions and the other has HAPs emissions) they need to be processed in this function together to avoid double counting in speciation. (If you will not be speciating the emissions, then it doesn't matter.) f is an optional filter function to determine which records should be kept. If f is nil, all records will be kept. The caller is responsible for closing the files.

type GridCell

type GridCell struct {
	geom.Polygonal
	Row, Col int
	Weight   float64
	TimeZone string
}

GridCell defines an individual cell in a grid.

func (*GridCell) Copy

func (c *GridCell) Copy() *GridCell

Copy copies a grid cell.

type GridDef

type GridDef struct {
	Name          string
	Nx, Ny        int
	Dx, Dy        float64
	X0, Y0        float64
	Cells         []*GridCell
	SR            *proj.SR
	Extent        geom.Polygon
	IrregularGrid bool // whether the grid is a regular grid
	// contains filtered or unexported fields
}

GridDef specifies the grid that we are allocating the emissions to.

func NewGridIrregular

func NewGridIrregular(Name string, g []geom.Polygonal, inputSR, outputSR *proj.SR) (grid *GridDef, err error)

NewGridIrregular creates a new irregular grid. g is the grid geometry. Irregular grids have 1 column and n rows, where n is the number of shapes in g. inputSR is the spatial reference of g, and outputSR is the desired spatial reference of the grid.

func NewGridRegular

func NewGridRegular(Name string, Nx, Ny int, Dx, Dy, X0, Y0 float64,
	sr *proj.SR) (grid *GridDef)

NewGridRegular creates a new regular grid, where all grid cells are the same size.

func (*GridDef) GetIndex

func (grid *GridDef) GetIndex(g geom.Geom) (rows, cols []int, fracs []float64, inGrid, coveredByGrid bool)

GetIndex gets the returns the row and column indices of geometry g in the grid. withinGrid is false if point (X,Y) is not within the grid. g can be a Point, Line, or Polygon. For lines and polygons, the fraction of g that is in each grid cell is returned as fracs. If g is a point, usually there will be only one row and column for each point, but it the point lies on a shared edge among multiple grid cells, all of the overlapping grid cells will be returned.

func (*GridDef) WriteToShp

func (grid *GridDef) WriteToShp(outdir string) error

WriteToShp writes the grid definition to a shapefile in directory outdir.

type GridRef

type GridRef struct {
	// contains filtered or unexported fields
}

GridRef specifies the grid surrogates the correspond with combinations of country (first map), SCC (second map), and FIPS or spatial ID (third map).

func ReadGridRef

func ReadGridRef(f io.Reader, sccExactMatch bool) (*GridRef, error)

ReadGridRef reads the SMOKE gref file, which maps FIPS and SCC codes to grid surrogates. sccExactMatch specifies whether SCC codes must match exactly, or if partial matches are allowed.

func (GridRef) GetSrgCode

func (gr GridRef) GetSrgCode(SCC string, c Country, FIPS string) (string, error)

GetSrgCode returns the surrogate code appropriate for the given SCC code, country and FIPS.

func (*GridRef) Merge

func (gr *GridRef) Merge(gr2 *GridRef) error

Merge combines values in gr2 into gr. If gr2 combines any values that conflict with values already in gr, an error is returned.

type GriddedSrgData

type GriddedSrgData struct {
	InputLocation        *Location
	Cells                []*GridCell
	SingleShapeSrgWeight float64
	CoveredByGrid        bool
	Nx, Ny               int
}

GriddedSrgData holds the data for a single input shape of a gridding surrogate.

func (*GriddedSrgData) ToGrid

func (gs *GriddedSrgData) ToGrid() (*sparse.SparseArray, bool)

ToGrid allocates the 1 unit of emissions associated with shapeID to a grid based on gs. It will return nil if there is no surrogate for the specified shapeID or if the sum of the surrogate is zero. The second returned value indicates whether the shape corresponding to shapeID is completely covered by the grid.

func (*GriddedSrgData) WriteToShp

func (g *GriddedSrgData) WriteToShp(file string) error

WriteToShp write an individual gridding surrogate to a shapefile.

type InputUnits

type InputUnits int

InputUnits specify available options for emissions input units.

const (
	// Ton is short tons
	Ton InputUnits = iota
	// Tonne is metric tons
	Tonne
	// Kg is kilograms
	Kg
	// G is grams
	G
	// Lb is pounds
	Lb
)

func ParseInputUnits

func ParseInputUnits(units string) (InputUnits, error)

ParseInputUnits parses a string representation of an input unit type. Currently supported options are "tons", "tonnes", "kg", "lbs", and "g".

func (InputUnits) Conversion

func (u InputUnits) Conversion(factor float64) func(v float64) *unit.Unit

Conversion returns a function that converts a value to units of kilograms. factor reprents an additional factor the value should be multiplied by.

type InventoryFile

type InventoryFile struct {
	io.ReadSeeker

	// Period is the time period that the emissions in this file apply to.
	Period
	// contains filtered or unexported fields
}

An InventoryFile reads information from and stores information about an emissions inventory file.

func NewInventoryFile

func NewInventoryFile(name string, r io.ReadSeeker, p Period, inputConverter func(float64) *unit.Unit) (*InventoryFile, error)

NewInventoryFile sets up a new InventoryFile with name name and reader r. p specifies the time period that the emissions are effective during, and inputConverter is a function to convert the input data to SI units.

func (*InventoryFile) DroppedTotals

func (f *InventoryFile) DroppedTotals() map[Pollutant]*unit.Unit

DroppedTotals returns the total emissions in this file that are not being kept for analysis.

func (*InventoryFile) Group

func (f *InventoryFile) Group() string

Group is a label for the group of files this is part of. It is used for reporting.

func (*InventoryFile) Name

func (f *InventoryFile) Name() string

Name is the name of this file. It can be the path to the file or something else.

func (*InventoryFile) Totals

func (f *InventoryFile) Totals() map[Pollutant]*unit.Unit

Totals returns the total emissions in this file, disaggregated by pollutant.

type InventoryFrequency

type InventoryFrequency string

InventoryFrequency describes how many often new inventory files are required.

const (
	Annually InventoryFrequency = "annual"
	Monthly  InventoryFrequency = "monthly"
)

Inventory frequencies can either be annual or monthly

type InventoryReport

type InventoryReport struct {
	Data []Totaler
}

An InventoryReport report holds information about inventory data.

func (*InventoryReport) AddData

func (ir *InventoryReport) AddData(data ...Totaler)

AddData adds file(s) to the report.

func (*InventoryReport) DroppedTotalsTable

func (ir *InventoryReport) DroppedTotalsTable() Table

DroppedTotalsTable returns a table of the total emissions in this report, where the rows are the files and the columns are the pollutants, arranged alphabetically.

func (*InventoryReport) TotalsTable

func (ir *InventoryReport) TotalsTable() Table

TotalsTable returns a table of the total emissions in this report, where the rows are the files and the columns are the pollutants, arranged alphabetically.

type Location

type Location struct {
	geom.Geom
	SR   *proj.SR
	Name string
}

func (*Location) Reproject

func (l *Location) Reproject(sr *proj.SR) (geom.Geom, error)

func (*Location) String

func (l *Location) String() string

type Mechanisms

type Mechanisms struct {
	// MechAssigment holds chemical mechanism assignment information
	// for individiaul chemical species.
	// Data should be in the format:
	// map[mechanism][SPECIATE ID][mechanism group]ratio.
	MechAssignment map[string]map[string]map[string]float64

	// MechMW holds molecular weight information for chemical
	// mechanism species. Data should be in the format:
	// map[mechanism][mechanism group]{massOrMol,MW}
	MechMW map[string]map[string]mechData

	// SpecInfo holds name and molecular weight information
	// for individual chemical species.
	// Data should be in the format:
	// map[SPECIATE ID]{name, MW}
	SpecInfo map[string]specInfo
}

Mechanisms holds information on chemical speciation mechanisms as specified at http://www.cert.ucr.edu/~carter/emitdb/.

func NewMechanisms

func NewMechanisms(mechAssignment, molarWeight, speciesInfo io.Reader) (*Mechanisms, error)

NewMechanisms returns a new Mechanisms variable initialized with information from mechanism assignment, molecular weight, and species information files in the format specified at http://www.cert.ucr.edu/~carter/emitdb/. (The files on the website must first be converted from Microsoft Excel to CSV format before being read by this function.)

func (*Mechanisms) GroupFactors

func (m *Mechanisms) GroupFactors(mechanism, speciesID string, mass bool) (map[string]float64, error)

GroupFactors returns the factors by which to multiply the given chemical species by to convert it to the given chemical mechanism. If mass is true, the multipliers will be adjusted so as to conserve the mass of the input species, so the units will be [mass/mass]. Otherwise, the factors will be computed so as to convert the chemical amount to a molar basis and the units will be [mol/gram]. The species to chemical mechanism conversion database (http://www.cert.ucr.edu/~carter/emitdb/) is designed to (attempt to) conserve reactivity rather than moles or mass, so for molar speciation the total number of moles may not be conserved.

type Period

type Period int

Period specifies the time period of the emissions data.

const (
	Jan Period = iota + 1
	Feb
	Mar
	Apr
	May
	Jun
	Jul
	Aug
	Sep
	Oct
	Nov
	Dec
	Annual
	Cem
)

The Periods are the months of the year, annual, or Cem which is hourly continuous emissions monitoring data.

func PeriodFromTimeInterval

func PeriodFromTimeInterval(start, end time.Time) (Period, error)

PeriodFromTimeInterval returns the period associated with the given time interval.

func (Period) String

func (p Period) String() string

func (Period) TimeInterval

func (p Period) TimeInterval(year string) (start, end time.Time, err error)

TimeInterval returns the start and the end of the receiver period in the given year.

type PointRecord

PointRecord holds information about an emissions source that has a point location.

func (*PointRecord) Key

func (r *PointRecord) Key() string

Key returns a unique key for this record.

type PointSourceData

type PointSourceData struct {
	// PlantID is the Plant Identification Code (15 characters maximum) (required,
	// this is the same as the State Facility Identifier in the NIF)
	PlantID string

	// PointID is the Point Identification Code (15 characters maximum) (required,
	// this is the same as the Emission Unit ID in the NIF)
	PointID string

	// StackID is the Stack Identification Code (15 characters maximum) (recommended,
	// this is the same as the Emissions Release Point ID in the NIF)
	StackID string

	// Segement is the DOE Plant ID (15 characters maximum) (recommended, this is the
	// same as the Process ID in the NIF)
	Segment string

	// Plant Name (40 characters maximum) (recommended)
	Plant string

	// DOE Plant ID (generally recommended, and required if matching
	// to hour-specific CEM data)
	ORISFacilityCode string

	// Boiler Identification Code (recommended)
	ORISBoilerID string

	// Stack Height (m) (required)
	StackHeight *unit.Unit

	// Stack Diameter (m) (required)
	StackDiameter *unit.Unit

	// Stack Gas Exit Temperature (K) (required)
	StackTemp *unit.Unit

	// Stack Gas Flow Rate (m3/sec) (optional)
	StackFlow *unit.Unit

	// Stack Gas Exit Velocity (m/sec) (required)
	StackVelocity *unit.Unit

	// Point holds the location of the emissions source
	geom.Point

	// SR holds the spatial reference system of the coordinates of this point
	SR *proj.SR
}

PointSourceData holds information specific to point emissions sources.

func (*PointSourceData) GroundLevel

func (r *PointSourceData) GroundLevel() bool

GroundLevel returns true if the receiver emissions are at ground level and false if they are elevated.

func (*PointSourceData) Key

func (r *PointSourceData) Key() string

Key returns a unique key for this record.

func (*PointSourceData) Location

func (r *PointSourceData) Location() *Location

func (*PointSourceData) StackParameters

func (r *PointSourceData) StackParameters() (StackHeight, StackDiameter, StackTemp, StackFlow, StackVelocity *unit.Unit)

StackParameters describes the parameters of the emissions release from a elevated stack.

type Pollutant

type Pollutant struct {
	// Name is the name of the pollutant.
	Name string

	// Prefix holds information about the pollutant prefix, such as BRK, TIR, etc.
	Prefix string
}

Pollutant holds information about a pollutant.

func (Pollutant) String

func (p Pollutant) String() string

type PolygonRecord

type PolygonRecord struct {
	SourceDataLocation
	EconomicData
	ControlData
	Emissions
}

PolygonRecord holds information about an emissions source that has an area (i.e., polygon) location. The polygon is designated by the SourceData.FIPS code.

func (*PolygonRecord) PointData

func (r *PolygonRecord) PointData() *PointSourceData

PointData exists to fulfill the Record interface but always returns nil because this is not a point source.

type RecFilter

type RecFilter func(Record) bool

RecFilter is a class of functions that return true if a record should be kept and processed.

type Record

type Record interface {
	// Key returns a unique identifier for this record.
	Key() string

	// Location returns the polygon representing the location of emissions.
	Location() *Location

	// GetSCC returns the SCC associated with this record.
	GetSCC() string

	// GetFIPS returns the FIPS associated with this record.
	GetFIPS() string

	// GetCountry returns the Country associated with this record.
	GetCountry() Country

	// GetEmissions returns the emissions associated with this record
	GetEmissions() *Emissions

	// CombineEmissions combines emissions from r2 into this record.
	CombineEmissions(r2 Record)

	// Totals returns the total emissions in units of grams.
	Totals() map[Pollutant]*unit.Unit

	// PeriodTotals returns the total emissions from this emissions source between
	// the times begin and end.
	PeriodTotals(begin, end time.Time) map[Pollutant]*unit.Unit
}

A Record holds data from a parsed emissions inventory record.

func NewFF10DailyPoint

func NewFF10DailyPoint(rec []string, annualBegin, annualEnd time.Time, periods [12]*monthPeriod, inputConv func(float64) *unit.Unit) (Record, error)

NewFF10DailyPoint creates a new record from the FF10 daily point record rec, where periods specify the periods when the emissions occur (the 12 months) and inputConv specifies the factor to multiply emissions by to convert them to SI units.

func NewFF10Nonpoint

func NewFF10Nonpoint(rec []string, annualBegin, annualEnd time.Time,
	periods [12]*monthPeriod, inputConv func(float64) *unit.Unit) (Record, error)

NewFF10Nonpoint creates a new record from the FF10 nonpoint record rec, where annualBegin and annualEnd specify the period that annual total emissions occur over, 'periods' specifies the periods when the monthly emissions occur

and inputConv specifies the factor

to multiply emissions by to convert them to SI units.

func NewFF10Point

func NewFF10Point(rec []string, annualBegin, annualEnd time.Time,
	periods [12]*monthPeriod, inputConv func(float64) *unit.Unit) (Record, error)

NewFF10Point creates a new record from the FF10 point record rec, where annualBegin and annualEnd specify the period that annual total emissions occur over, 'periods' specifies the periods when the monthly emissions occur

and inputConv specifies the factor

to multiply emissions by to convert them to SI units.

func NewIDAArea

func NewIDAArea(rec string, pollutants []string, country Country, begin, end time.Time, inputConv func(float64) *unit.Unit) (Record, error)

NewIDAArea creates a new record from the IDA area record rec, where pollutants are the names of the pollutants in the record, country is the country and year of the emissions, begin and end specify the time period this record covers, and inputConv specifies the factor to multiply emissions by to convert them to SI units.

func NewIDAMobile

func NewIDAMobile(rec string, pollutants []string, country Country, begin, end time.Time, inputConv func(float64) *unit.Unit) (Record, error)

NewIDAMobile creates a new record from the IDA mobile record rec, where pollutants are the names of the pollutants in the record, country is the country and year of the emissions, begin and end specify the time period this record covers, and inputConv specifies the factor to multiply emissions by to convert them to SI units.

func NewIDAPoint

func NewIDAPoint(rec string, pollutants []string, country Country, begin, end time.Time, inputConv func(float64) *unit.Unit) (Record, error)

NewIDAPoint creates a new record from the IDA point record rec, where pollutants are the names of the pollutants in the record, country is the country and year of the emissions, begin and end specify the time period this record covers, and inputConv specifies the factor to multiply emissions by to convert them to SI units.

func NewORLMobile

func NewORLMobile(rec []string, country Country, begin, end time.Time, inputConv func(float64) *unit.Unit) (Record, error)

NewORLMobile creates a new record from the ORL mobile record rec, where country is the country and year of the emissions, begin and end specify the time period this record covers, inputConv specifies the factor to multiply emissions by to convert them to SI units.

func NewORLNonpoint

func NewORLNonpoint(rec []string, country Country, begin, end time.Time, inputConv func(float64) *unit.Unit) (Record, error)

NewORLNonpoint creates a new record from the ORL nonpoint record rec, where country is the country and year of the emissions, begin and end specify the time period this record covers, and inputConv specifies the factor to multiply emissions by to convert them to SI units.

func NewORLNonroad

func NewORLNonroad(rec []string, country Country, begin, end time.Time, inputConv func(float64) *unit.Unit) (Record, error)

NewORLNonroad creates a new record from the ORL nonroad record rec, where country is the country and year of the emissions, begin and end specify the time period this record covers, inputConv specifies the factor to multiply emissions by to convert them to SI units.

func NewORLPoint

func NewORLPoint(rec []string, country Country, begin, end time.Time, inputConv func(float64) *unit.Unit) (Record, error)

NewORLPoint creates a new record from the ORL point record rec, where country is the country and year of the emissions, begin and end specify the time period this record covers, and inputConv specifies the factor to multiply emissions by to convert them to SI units.

type RecordElevated

type RecordElevated interface {
	Record

	// StackParameters describes the parameters of the emissions release
	// from a elevated stack.
	StackParameters() (StackHeight, StackDiameter, StackTemp, StackFlow, StackVelocity *unit.Unit)

	// GroundLevel returns true if the receiver emissions are
	// at ground level and false if they are elevated.
	GroundLevel() bool
}

RecordElevated describes emissions that are released from above ground.

type RecordGridded

type RecordGridded interface {
	Record

	// Parent returns the record that this record was created from.
	Parent() Record

	// GridFactors returns the normalized fractions of emissions in each
	// grid cell (gridSrg) of grid index gi.
	// coveredByGrid indicates whether the emissions source is completely
	// covered by the grid, and inGrid indicates whether it is in the
	// grid at all.
	GridFactors(gi int) (gridSrg *sparse.SparseArray, coveredByGrid, inGrid bool, err error)

	// GriddedEmissions returns gridded emissions of the receiver for a given grid index and period.
	GriddedEmissions(begin, end time.Time, gi int) (
		emis map[Pollutant]*sparse.SparseArray, units map[Pollutant]unit.Dimensions, err error)
}

RecordGridded represents an emissions record that can be allocated to a spatial grid.

type RecordGriddedAdjusted

type RecordGriddedAdjusted struct {
	// RecordGridded is the record to be adjusted.
	RecordGridded

	// SpatialAdjuster specifies the adjustment to occur.
	SpatialAdjuster
}

RecordGriddedAdjusted wraps around a RecordGridded to provide a spatially-explicit adjustment.

func (*RecordGriddedAdjusted) GridFactors

func (r *RecordGriddedAdjusted) GridFactors(gi int) (
	gridSrg *sparse.SparseArray, coveredByGrid, inGrid bool, err error)

GridFactors calls the GridFactors method of the contained Record and adjusts the output using the SpatialAdjuster field.

func (*RecordGriddedAdjusted) GriddedEmissions

func (r *RecordGriddedAdjusted) GriddedEmissions(begin, end time.Time, gi int) (
	emis map[Pollutant]*sparse.SparseArray, units map[Pollutant]unit.Dimensions, err error)

GriddedEmissions calls the GriddedEmissions method of the contained Record and adjusts the output using the SpatialAdjuster field.

type RecordSpatialSurrogate

type RecordSpatialSurrogate interface {
	Record

	// Parent returns the record that this record was created from.
	Parent() Record

	// SurrogateSpecification returns the specification of the spatial surrogate
	// associated with an area emissions source.
	SurrogateSpecification() (SrgSpec, error)
}

RecordSpatialSurrogate describes emissions that need to be allocated to a grid using a spatial surrogate.

type SourceData

type SourceData struct {
	// Five digit FIPS code for state and county (required)
	FIPS string

	// Ten character Source Classification Code (required)
	SCC string

	// Source type (2 characters maximum), used by SMOKE in determining
	// applicable MACT-based controls (required)
	// 	01 = major
	// 	02 = Section 12 area source
	// 	03 = nonroad
	// 	04 = onroad
	SourceType string

	// The country that this record applies to.
	Country Country
}

SourceData holds information about the type of an emissions source.

func (SourceData) GetCountry

func (r SourceData) GetCountry() Country

GetCountry returns the Country associated with this record.

func (SourceData) GetFIPS

func (r SourceData) GetFIPS() string

GetFIPS returns the FIPS associated with this record.

func (SourceData) GetSCC

func (r SourceData) GetSCC() string

GetSCC returns the SCC associated with this record.

func (SourceData) GetSourceData

func (r SourceData) GetSourceData() *SourceData

GetSourceData returns r.

func (*SourceData) Key

func (r *SourceData) Key() string

Key returns a unique key for this record.

type SourceDataLocation

type SourceDataLocation struct {
	SourceData
	// contains filtered or unexported fields
}

func (*SourceDataLocation) Location

func (r *SourceDataLocation) Location() *Location

Location returns the polygon representing the location of emissions.

func (*SourceDataLocation) SurrogateSpecification

func (r *SourceDataLocation) SurrogateSpecification(sp *SpatialProcessor) (SrgSpec, error)

SurrogateSpecification returns the specification of the spatial surrogate associated with an area emissions source.

type SpatialAdjuster

type SpatialAdjuster interface {
	Adjustment() (*sparse.DenseArray, error)
}

SpatialAdjuster is an interface for types that provide gridded adjustments to Records.

type SpatialProcessor

type SpatialProcessor struct {
	SrgSpecs *SrgSpecs
	Grids    []*GridDef
	GridRef  *GridRef

	// DiskCachePath specifies a directory to cache surrogate files in. If it is
	// empty or invalid, surrogates will not be stored on the disk for later use.
	DiskCachePath string

	// MemCacheSize specifies the number of surrogates to hold in the memory cache.
	// A larger number results in potentially faster performance but more memory use.
	// The default is 100.
	MemCacheSize int

	// MaxMergeDepth is the maximum number of nested merged surrogates.
	// For example, if surrogate 100 is a combination of surrogates 110 and 120,
	// and surrogate 110 is a combination of surrogates 130 and 140, then
	// MaxMergeDepth should be set to 3, because 100 depends on 110 and 110
	// depends on 130. If MaxMergeDepth is set too low, the program may hang
	// when attempting to create a merged surrogate.
	// The default value is 10.
	MaxMergeDepth int

	// SimplifyTolerance specifies the length of features up to which to remove
	// when simplifying shapefiles for spatial surrogate creation. The default is
	// 0 (i.e., no simplification). Simplifying decreases processing time and
	// memory use. The value should be in the units of the output grid
	// (e.g., meters or degrees).
	SimplifyTolerance float64

	// SrgCellRatio is the number of surrogate shapes to process per
	// grid cell for each input shape. Larger numbers require
	// longer to compute. If srgCellRatio > 1, all surrogate
	// shapes will be processed.
	SrgCellRatio int

	MsgChan chan string
	// contains filtered or unexported fields
}

SpatialProcessor spatializes emissions records.

func NewSpatialProcessor

func NewSpatialProcessor(srgSpecs *SrgSpecs, grids []*GridDef, gridRef *GridRef, inputSR *proj.SR, matchFullSCC bool) *SpatialProcessor

NewSpatialProcessor creates a new spatial processor.

func (*SpatialProcessor) AddSurrogate

func (sp *SpatialProcessor) AddSurrogate(r Record) RecordSpatialSurrogate

AddSurrogate adds a spatial surrogate to a record to increase its spatial resolution.

func (*SpatialProcessor) GridRecord

func (sp *SpatialProcessor) GridRecord(r Record) RecordGridded

GridRecord returns a record that can allocate the emissions to a grid.

func (*SpatialProcessor) Surrogate

func (sp *SpatialProcessor) Surrogate(srgSpec SrgSpec, grid *GridDef, loc *Location) (*sparse.SparseArray, bool, error)

Surrogate gets the specified spatial surrogate. It is important not to edit the returned surrogate in place, because the same copy is used over and over again. The second return value indicates whether the shape corresponding to fips is completely covered by the grid.

type SpecRef

type SpecRef struct {
	// contains filtered or unexported fields
}

SpecRef holds speciation reference information extracted from SMOKE model gsref files.

func NewSpecRef

func NewSpecRef(ref, refCombo io.Reader) (*SpecRef, error)

NewSpecRef returns a new SpecRef variable created from the information in the given readers.

func (*SpecRef) Codes

func (sp *SpecRef) Codes(SCC string, pol Pollutant, start, end time.Time, c Country, FIPS string, partialMatch bool) (map[string]float64, error)

Codes returns the speciation profile code(s) that match the given SCC code, pollutant (pol), time period (start and end), country, and FIPS location code, along with the fraction of speciation that should be attributed to each code. If partialMatch is false, only codes exactly matching the given SCC will be returned, otherwise if no match is found an attempt will be made to return a code matching a more general SCC. If no direct match is found for pol, an attempt will be made to find a match for a version of pol without its prefix.

type SpeciateDB

type SpeciateDB struct {
	// SpeciesProperties maps speciate IDs to chemical names and
	// molecular weights.
	SpeciesProperties map[string]struct {
		Name string
		MW   float64
	}

	// VOCToTOG holds the conversion factor from VOC mass to TOG mass
	// for VOCs in different speciation profiles.
	VOCToTOG map[string]float64

	// VOCProfiles maps aggregated VOCs to individual VOC species.
	// Format: map[speciation code][species ID]weight
	VOCProfiles map[string]map[string]float64

	// OtherGasProfiles maps aggregated non-VOC gases
	// such as NOx to individual chemical species.
	// Format: map[speciation code][species ID]weight
	OtherGasProfiles map[string]map[string]float64

	// PMProfiles maps aggregated particulate matter species
	// to individual chemical species.
	// Format: map[speciation code][species ID]weight
	PMProfiles map[string]map[string]float64
}

SpeciateDB holds information extracted from the SPECIATE database. (https://www.epa.gov/air-emissions-modeling/tools-related-air-emissions-modeling)

func NewSpeciateDB

func NewSpeciateDB(speciesProperties, gasProfile, gasSpecies, otherGasSpecies, pmSpecies io.Reader) (*SpeciateDB, error)

NewSpeciateDB returns a new SpeciateDB variable filled with information from the SPECIATE database, where the arguments are readers of the similarly named tables in the database, exported to CSV format. The SPECIATE database is available at: https://www.epa.gov/air-emissions-modeling/speciate-version-45-through-32. To export the tables in CSV format in Linux, use the mdb-export command:

mdb-export SPECIATE.mdb SPECIES_PROPERTIES > SPECIES_PROPERTIES.csv
mdb-export SPECIATE.mdb GAS_PROFILE > GAS_PROFILE.csv
mdb-export SPECIATE.mdb GAS_SPECIES > GAS_SPECIES.csv
mdb-export SPECIATE.mdb OTHER\ GASES_SPECIES > OTHER_GASES_SPECIES.csv
mdb-export SPECIATE.mdb PM_SPECIES > PM_SPECIES.csv

func (*SpeciateDB) IDFromName

func (s *SpeciateDB) IDFromName(name string) (string, error)

IDFromName returns the SPECIATE ID associated with the given species name.

func (*SpeciateDB) Speciation

func (s *SpeciateDB) Speciation(code string, Type SpeciationType) (map[string]float64, error)

Speciation returns the speciation fractions for the given speciation profile code and specition type. Valid Type options are "VOC", "NOx", and "PM2.5". The output is in the format map[SPECIATE ID]fraction.

type Speciation

type Speciation map[string]struct {
	// SpecType specifies a type of speciation to be applied.
	// Options are "VOC","PM2.5", and "NOx".
	// If empty, the pollutant will be carried through to
	// the output without speciation, or grouped as
	// if it were the pollutants in "SpecNames".
	SpecType SpeciationType

	// SpecNames contains names of pollutants in the SPECIATE
	// database which are equivalent to this pollutant.
	// For records containing this pollutant, the pollutants
	// included in "SpecNames.Names" will be left out of any
	// speciation that occurs to avoid double counting.
	SpecNames struct {
		// Names are the SPECIATE names that are equivalent to this
		// pollutant.
		Names []string
		// Group specifies whether this pollutant should be
		// grouped into a chemical mechanism.
		Group bool
	}

	// SpecProf can be used to directly specify speciation
	// factors. Conversion from mass to moles, if required,
	// must be included in the provided factors.
	//
	// BUG: The current implementation won't change the units of the emissions, so
	// if a unit conversion was included in the factor it won't be reflected
	// in the speciated result.
	SpecProf map[string]float64
}

Speciation specifies the pollutant names that should be kept for analysis and information about how to chemically speciate each one. PolInfo holds the configuration of chemical speciation settings for individual pollutants. Only one of the fields should be used for each pollutant.

func (Speciation) Names

func (s Speciation) Names(p Pollutant) ([]string, bool, error)

Names returns the equivalent SPECIATE names of p and whether they should each be grouped into a chemical mechanism. If there is not an exact match for p, it will return the speciation type of p without its prefix. If that fails, or if the SpeciationType of p is not SingleSpecies, it will return an error.

func (Speciation) Profile

func (s Speciation) Profile(p Pollutant) (map[string]float64, error)

Profile returns the directly specified speciation profile for p. If there is not an exact match, it will return the speciation profile for p without its prefix. If that fails, or if the SpeciationType of p is not Direct, it will return an error.

func (Speciation) Type

Type returns the SpeciationType of p. If there is not an exact match, it will return the speciation type of p without its prefix. If that fails, it will return an error.

type SpeciationType

type SpeciationType string

SpeciationType specifies the available speciation types.

type Speciator

type Speciator struct {
	SpecRef    *SpecRef
	SpeciateDB *SpeciateDB
	Mechanisms *Mechanisms
	Speciation Speciation
}

Speciator speciates emissions in Records from more aggregated chemical groups to more specific chemical groups.

func NewSpeciator

func NewSpeciator(specRef, specRefCombo, speciesProperties, gasProfile, gasSpecies, otherGasSpecies, pmSpecies, mechAssignment, molarWeight, speciesInfo io.Reader, speciation Speciation) (*Speciator, error)

NewSpeciator returns a new Speciator variable.

func (*Speciator) Speciate

func (s *Speciator) Speciate(r Record, mechanism string, mass, partialMatch bool) (emis, dropped *Emissions, err error)

Speciate disaggregates the lumped emissions species in the given Record into the species groups in the given chemical mechanism. If mass is true, speciation is done on a mass basis, otherwise emissions will be converted to molar units for gases (but not for particulates). If partialMatch is true, matches to speciation profile codes will be made based on parital matches to SCC codes if full matches are not available.

type SrgSpec

type SrgSpec interface {
	// contains filtered or unexported methods
}

type SrgSpecOSM

type SrgSpecOSM struct {
	Region Country `json:"region"`
	Name   string  `json:"name"`
	Code   string  `json:"code"`

	OSMFile string `json:"osm_file"`

	Tags map[string][]string `json:"tags"`

	// BackupSurrogateNames specifies names of surrogates to use if this
	// one doesn't have data for the desired location.
	BackupSurrogateNames []string `json:"backup_surrogate_names"`

	// MergeNames specify names of other surrogates that should be combined
	// to create this surrogate.
	MergeNames []string `json:"merge_names"`
	// MergeMultipliers specifies multipliers associated with the surrogates
	// in MergeNames.
	MergeMultipliers []float64 `json:"merge_multipliers"`
	// contains filtered or unexported fields
}

SrgSpecOSM holds OpenStreetMap spatial surrogate specification information.

type SrgSpecSMOKE

type SrgSpecSMOKE struct {
	Region          Country
	Name            string
	Code            string
	DATASHAPEFILE   string
	DATAATTRIBUTE   string
	WEIGHTSHAPEFILE string
	Details         string

	// BackupSurrogateNames specifies names of surrogates to use if this
	// one doesn't have data for the desired location.
	BackupSurrogateNames []string

	// WeightColumns specify the fields of the surogate shapefile that
	// should be used to weight the output locations.
	WeightColumns []string

	// WeightFactors are factors by which each of the WeightColumns should
	// be multiplied.
	WeightFactors []float64

	// FilterFunction specifies which rows in the surrogate shapefile should
	// be used to create this surrogate.
	FilterFunction *SurrogateFilter

	// MergeNames specify names of other surrogates that should be combined
	// to create this surrogate.
	MergeNames []string
	// MergeMultipliers specifies multipliers associated with the surrogates
	// in MergeNames.
	MergeMultipliers []float64
	// contains filtered or unexported fields
}

SrgSpecSMOKE holds SMOKE-formatted spatial surrogate specification information. See the SMOKE emissions model technical documentation for additional information.

func (*SrgSpecSMOKE) InputShapes

func (srg *SrgSpecSMOKE) InputShapes() (map[string]*Location, error)

InputShapes returns the input shapes associated with the receiver.

type SrgSpecs

type SrgSpecs struct {
	// contains filtered or unexported fields
}

SrgSpecs holds a group of surrogate specifications

func NewSrgSpecs

func NewSrgSpecs() *SrgSpecs

NewSrgSpecs initializes a new SrgSpecs object.

func ReadSrgSpecOSM

func ReadSrgSpecOSM(r io.Reader, diskCachePath string, memCacheSize int) (*SrgSpecs, error)

ReadSrgSpec reads a OpenStreetMap surrogate specification formated as a JSON array of SrgSpecOSM objects. diskCachePath specifies a path to a directory where an on-disk cache should be created (if "", no cache will be created), and memCacheSize specifies the number of surrogate data entries to hold in an in-memory cache.

func ReadSrgSpecSMOKE

func ReadSrgSpecSMOKE(fid io.Reader, shapefileDir string, checkShapefiles bool, diskCachePath string, memCacheSize int) (*SrgSpecs, error)

ReadSrgSpecSMOKE reads a SMOKE formatted spatial surrogate specification file. Results are returned as a map of surrogate specifications as indexed by their unique ID, which is Region+SurrogateCode. shapefileDir specifies the location of all the required shapefiles, and checkShapeFiles specifies whether to check if the required shapefiles actually exist. If checkShapeFiles is true, then it is okay for the shapefiles to be in any subdirectory of shapefileDir, otherwise all shapefiles must be in shapefileDir itself and not a subdirectory. diskCachePath specifies a path to a directory where an on-disk cache should be created (if "", no cache will be created), and memCacheSize specifies the number of surrogate data entries to hold in an in-memory cache.

func (*SrgSpecs) Add

func (s *SrgSpecs) Add(ss SrgSpec)

Add adds a new SrgSpec to s.

func (*SrgSpecs) AddAll

func (s *SrgSpecs) AddAll(srgs *SrgSpecs)

AddAll adds all surrogates in srgs to the receiver.

func (*SrgSpecs) GetByCode

func (s *SrgSpecs) GetByCode(region Country, code string) (SrgSpec, error)

GetByCode gets the surrogate matching the given region and code.

func (*SrgSpecs) GetByName

func (s *SrgSpecs) GetByName(region Country, name string) (SrgSpec, error)

GetByName gets the surrogate matching the given region and name.

type Status

type Status struct {
	// Name and Code hold information about the job
	Name, Code string

	// Status holds information about the status of the job.
	Status string

	// Progress holds information about how close the job is to completion.
	Progress float64
}

Status holds information on the progress or status of a job.

type SurrogateFilter

type SurrogateFilter struct {
	Column        string
	EqualNotEqual string
	Values        []string
}

SurrogateFilter can be used to limit which rows in a shapefile are used to create a gridding surrogate.

func ParseSurrogateFilter

func ParseSurrogateFilter(filterFunction string) *SurrogateFilter

ParseSurrogateFilter creates a new surrogate filter object from a SMOKE-format spatial surrogate filter definition.

type Table

type Table [][]string

A Table holds a text representation of report data.

func (Table) Tabbed

func (t Table) Tabbed(w io.Writer) (n int, err error)

Tabbed creates a tab-separated table.

type Totaler

type Totaler interface {
	Totals() map[Pollutant]*unit.Unit
	DroppedTotals() map[Pollutant]*unit.Unit

	// Group returns the group that the receiver belongs to.
	Group() string

	// Name returns the name of the receiver.
	Name() string
}

Totaler is an interface for types than can return emissions totals and dropped emissions totals.

type WRFconfigData

type WRFconfigData struct {
	MaxDom             int
	ParentID           []int
	ParentGridRatio    []float64
	IParentStart       []int
	JParentStart       []int
	EWE                []int
	ESN                []int
	Dx0                float64
	Dy0                float64
	MapProj            string
	RefLat             float64
	RefLon             float64
	TrueLat1           float64
	TrueLat2           float64
	StandLon           float64
	RefX               float64
	RefY               float64
	S                  []float64
	W                  []float64
	Dx                 []float64
	Dy                 []float64
	Nx                 []int
	Ny                 []int
	DomainNames        []string
	FramesPerAuxInput5 []int
	Kemit              int
	Nocolons           bool
	// contains filtered or unexported fields
}

WRFconfigData hold information about a WRF simulation configuration.

func ParseWRFConfig

func ParseWRFConfig(wpsnamelist, wrfnamelist string) (d *WRFconfigData, err error)

ParseWRFConfig extracts configuration information from a set of WRF namelists.

func (*WRFconfigData) Grids

func (d *WRFconfigData) Grids() []*GridDef

Grids creates grid definitions for the grids in WRF configuration d, where tzFile is a shapefile containing timezone information, and tzColumn is the data attribute column within that shapefile that contains the timezone offsets in hours.

Directories

Path Synopsis
aeputil Package aeputil provides commonly used configuration and functions for the AEP library.