package module
v1.1.0 Latest Latest

This package is not in the latest version of its module.

Go to latest
Published: Feb 12, 2016 License: GPL-3.0 Imports: 33 Imported by: 2


(In)tervention (M)odel for (A)ir (P)ollution

Build Status Coverage Status GoDoc

About InMAP

InMAP is a multi-scale emissions-to-health impact model for fine particulate matter (PM2.5) that mechanistically evaluates air quality and health benefits of perturbations to baseline emissions. The main simplification of InMAP compared to a comprehensive chemical transport model is that it does so on an annual-average basis rather than the highly time-resolved performance of a full CTM. The model incorporates annual-average parameters (e.g. transport, deposition, and reaction rates) from the WRF/Chem chemical transport model. Grid-cell size varies as shown in Figure 1, ranging from smaller grid cells in urban areas to larger grid cells in rural areas; any grid cell above a specified population threshold is subdivided until no grid larger than 1 km has >10,000 people. This variable resolution grid is used to simulate population exposures to PM2.5 with high spatial resolution while minimizing computational expense.

alt tag Figure 1: InMAP spatial discretization of the model domain into variable resolution grid cells. Left panel: full domain; right panel: a small section of the domain centered on the city of Los Angeles.

Getting InMAP

Go to releases to download the most recent release for your type of computer. You will need both the executable program and the input data.

Compiling from source

You can also compile InMAP from its source code. It should work on most types of computers. Refer here for a list of theoretically supported systems. Instructions follow:

  1. Install the Go compiler. Make sure you install the correct version (32 or 64 bit) for your system. Also make sure to set the $GOPATH environment variable to a different directory than the $GOROOT environment variable (it can also not be a subdirectory of $GOROOT). It may be useful to go through one of the tutorials to make sure the compiler is correctly installed.

  2. Make sure your $PATH environment variable includes the directories $GOROOT/bin and $GOPATH/bin. On Linux or Macintosh systems, this can be done using the command export PATH=$PATH:$GOROOT/bin:$GOPATH/bin. On Windows systems, you can follow these directions.

  3. Install the git and mercurial version control programs, if they are not already installed. If you are using a shared system or cluster, you may just need to load them with the commands module load git and module load hg.

  4. Download and install the main program:

     go get

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

Running the InMAP example case

From the testdata directory in this website, download all of the files that match the pattern "inmap_*.gob" or "testEmis.*", where * is a wildcard that can match any set of characters. If you have followed the instructions in the "Compiling from source" section above you will already have downloaded these files. Next, download the file configExample.json and the InMAP executable program in the same directory. Next, open the file "configExample.json" with a text editor and delete the text "../testdata/" anywhere you see it. Finally, open a command prompt window, navigate to the directory where you saved the aforementioned files, and run the command inmap -config=configExample.json on Mac or Linux systems and inmap.exe -config=configExample.json on windows systems to run the program. The program should run without any error messages and create a file called "output_0.shp" (along with supporting files like "output_0.dbf") which can be viewed with any program that can view shapefiles. Refer to the next section for additional details.

Running InMAP

  1. Make sure that you have downloaded the general input files (InMAPData). It is important to download the version of the input files that match the version of InMAP you are using.

  2. Create an emissions scenario. Emissions files should be in shapefile format where the attribute columns correspond to the names of emitted pollutants. Refer here (the EmisNames variable) for acceptable pollutant names. Emissions should be in units of short tons per year. The model can handle multiple input emissions files, and emissions can be either elevated or ground level. Files with elevated emissions need to have attribute columns labeled "height", "diam", "temp", and "velocity" containing stack information in units of m, m, K, and m/s, respectively.

    Emissions will be allocated from the geometries in the shape file to the InMAP computational grid, but currently the mapping projection of the shapefile must be the same as the projection InMAP uses. In ESRI format, this projection is:

     PROJCS["Lambert_Conformal_Conic_2SP",GEOGCS["GCS_unnamed ellipse",
  3. Make a copy of the configuration file template and edit it so that the InMAPdataTemplate and EmissionsShapefiles variables point to the locations where you downloaded the general input and emissions files to, and so the OutputTemplate variable points to the desired location for the output files. The wildcard [layer] is a place holder for the vertical layer number. (Input and output data are separated into individual files by model layer). Refer directly to the source code (here) for information about other configuration options.

  4. Run the program:

     inmap -config=/path/to/configfile.json

    for Mac or Linux systems, and inmap.exe -config=/path/to/configfile.json for windows systems. While the program is running, you can open a web browser and navigate to localhost:8080 to view status and diagnostic information.

  5. View the program output. The output files are in shapefile format which can be viewed in most GIS programs. One free GIS program is QGIS. Output from each model layer is put into a separate file. Layer 0 is the one closest to the ground and will probably be of the most interest. By default, the InMAP only outputs results from layer zero, but this can be changed using the configuration file. The output shapefiles have a number of attribute columns. They include:

    • Pollutant concentrations in units of μg m-3:
      • VOC (VOC)
      • NOx (NOx)
      • NH3 (NH3)
      • SOx (SOx)
      • Total PM2.5 (TotalPM2_5; The sum of all PM2.5 components)
      • Particulate sulfate (pSO4)
      • Particulate nitrate (pNO3)
      • Particulate ammonium (pNH4)
      • Secondary organic aerosol (SOA)
    • Populations of different demographic subgroups in units of people per square meter. The included populations may vary but in the default dataset as of this writing the groups included are:
      • total population (TotalPop)
      • people identifying as black (Black), asian (Asian), latino (Latino), native american or american indian (Native), non-latino white (WhiteNoLat) and everyone else (Other).
      • People living below the poverty time (Poverty) and people living at more than twice the poverty line (TwoXPov).
    • Numbers of deaths attributable to PM2.5 in each of the populations in units of deaths/year. Attribute names in shapfiles are limited to 11 characters, so, for example, deaths in the TotalPop population would be labeled TotalPop de, deaths in the Black population would be labeled Black death, and—interestingly—deaths in the WhiteNoLat population would be labeled WhiteNoLat_1.
    • Baseline mortality rate in units of deaths per year per 100,000 people, which can be used for performing alternative health impact calculations.


The InMAP package is split into an executable program and an application programming interface (API). The documentation here shows the functions available in the API and how they work.




View Source
const (
	NOxToN = mwN / mwNOx
	NtoNO3 = mwNO3 / mwN
	SOxToS = mwSO2 / mwS
	StoSO4 = mwS / mwSO4
	NH3ToN = mwN / mwNH3
	NtoNH4 = mwNH4 / mwN

Chemical mass conversions [ratios]


View Source
var EmisNames = []string{"VOC", "NOx", "NH3", "SOx", "PM2_5"}

These are the names of pollutants accepted as emissions [μg/s]


This section is empty.


type Cell

type Cell struct {
	geom.T            // Cell geometry
	WebMapGeom geom.T // Cell geometry in web map (mercator) coordinate system

	UAvg       float64 `desc:"Average East-West wind speed" units:"m/s"`
	VAvg       float64 `desc:"Average North-South wind speed" units:"m/s"`
	WAvg       float64 `desc:"Average up-down wind speed" units:"m/s"`
	UDeviation float64 `desc:"Average deviation from East-West velocity" units:"m/s"`
	VDeviation float64 `desc:"Average deviation from North-South velocity" units:"m/s"`

	AOrgPartitioning float64 `desc:"Organic particle partitioning" units:"fraction particles"`
	BOrgPartitioning float64 // particle fraction
	SPartitioning    float64 `desc:"Sulfur particle partitioning" units:"fraction particles"`
	NOPartitioning   float64 `desc:"Nitrate particle partitioning" units:"fraction particles"`
	NHPartitioning   float64 `desc:"Ammonium particle partitioning" units:"fraction particles"`
	SO2oxidation     float64 `desc:"SO2 oxidation to SO4 by HO and H2O2" units:"1/s"`

	ParticleWetDep float64 `desc:"Particle wet deposition" units:"1/s"`
	SO2WetDep      float64 `desc:"SO2 wet deposition" units:"1/s"`
	OtherGasWetDep float64 `desc:"Wet deposition: other gases" units:"1/s"`
	ParticleDryDep float64 `desc:"Particle dry deposition" units:"m/s"`

	NH3DryDep float64 `desc:"Ammonia dry deposition" units:"m/s"`
	SO2DryDep float64 `desc:"SO2 dry deposition" units:"m/s"`
	VOCDryDep float64 `desc:"VOC dry deposition" units:"m/s"`
	NOxDryDep float64 `desc:"NOx dry deposition" units:"m/s"`

	Kzz                float64   `desc:"Grid center vertical diffusivity after applying convective fraction" units:"m²/s"`
	KzzAbove, KzzBelow []float64 // horizontal diffusivity [m2/s] (staggered grid)
	Kxxyy              float64   `desc:"Grid center horizontal diffusivity" units:"m²/s"`
	KyySouth, KyyNorth []float64 // horizontal diffusivity [m2/s] (staggered grid)
	KxxWest, KxxEast   []float64 // horizontal diffusivity at [m2/s] (staggered grid)

	M2u float64 `desc:"ACM2 upward mixing (Pleim 2007)" units:"1/s"`
	M2d float64 `desc:"ACM2 downward mixing (Pleim 2007)" units:"1/s"`

	PopData       map[string]float64 // Population for multiple demographics [people/grid cell]
	MortalityRate float64            `desc:"Baseline mortalities rate" units:"Deaths per 100,000 people per year"`

	Dx, Dy, Dz float64 // grid size [meters]
	Volume     float64 `desc:"Cell volume" units:"m³"`
	Row        int     // master cell index

	Ci []float64 // concentrations at beginning of time step [μg/m³]
	Cf []float64 // concentrations at end of time step [μg/m³]

	West        []*Cell // Neighbors to the East
	East        []*Cell // Neighbors to the West
	South       []*Cell // Neighbors to the South
	North       []*Cell // Neighbors to the North
	Below       []*Cell // Neighbors below
	Above       []*Cell // Neighbors above
	GroundLevel []*Cell // Neighbors at ground level
	Boundary    bool    // Does this cell represent a boundary condition?

	WestFrac, EastFrac   []float64 // Fraction of cell covered by each neighbor (adds up to 1).
	NorthFrac, SouthFrac []float64 // Fraction of cell covered by each neighbor (adds up to 1).
	AboveFrac, BelowFrac []float64 // Fraction of cell covered by each neighbor (adds up to 1).
	GroundLevelFrac      []float64 // Fraction of cell above to each ground level cell (adds up to 1).

	IWest        []int // Row indexes of neighbors to the East
	IEast        []int // Row indexes of neighbors to the West
	ISouth       []int // Row indexes of neighbors to the South
	INorth       []int // Row indexes of neighbors to the north
	IBelow       []int // Row indexes of neighbors below
	IAbove       []int // Row indexes of neighbors above
	IGroundLevel []int // Row indexes of neighbors at ground level

	DxPlusHalf  []float64 // Distance between centers of cell and East [m]
	DxMinusHalf []float64 // Distance between centers of cell and West [m]
	DyPlusHalf  []float64 // Distance between centers of cell and North [m]
	DyMinusHalf []float64 // Distance between centers of cell and South [m]
	DzPlusHalf  []float64 // Distance between centers of cell and Above [m]
	DzMinusHalf []float64 // Distance between centers of cell and Below [m]

	Layer int // layer index of grid cell

	Temperature                float64 `desc:"Average temperature" units:"K"`
	WindSpeed                  float64 `desc:"RMS wind speed" units:"m/s"`
	WindSpeedInverse           float64 `desc:"RMS wind speed inverse" units:"(m/s)^(-1)"`
	WindSpeedMinusThird        float64 `desc:"RMS wind speed^(-1/3)" units:"(m/s)^(-1/3)"`
	WindSpeedMinusOnePointFour float64 `desc:"RMS wind speed^(-1.4)" units:"(m/s)^(-1.4)"`
	S1                         float64 `desc:"Stability parameter" units:"?"`
	SClass                     float64 `desc:"Stability class" units:"0=Unstable; 1=Stable"`

	sync.RWMutex // Avoid cell being written by one subroutine and read by another at the same time.
	// contains filtered or unexported fields

Cell holds the state of a single grid cell.

func (*Cell) Chemistry

func (c *Cell) Chemistry(d *InMAPdata)

Chemistry calculates the secondary formation of PM2.5. It explicitely calculates formation of particulate sulfate from gaseous and aqueous SO2. It partitions organic matter ("gOrg" and "pOrg"), the nitrogen in nitrate ("gNO and pNO"), and the nitrogen in ammonia ("gNH" and "pNH) between gaseous and particulate phase based on the spatially explicit partioning present in the baseline data.

func (*Cell) DryDeposition

func (c *Cell) DryDeposition(d *InMAPdata)

DryDeposition calculates particle removal by dry deposition

func (*Cell) MeanderMixing

func (c *Cell) MeanderMixing(Δt float64)

MeanderMixing calculates changes in concentrations caused by meanders: adevection that is resolved by the underlying comprehensive chemical transport model but is not resolved by InMAP.

func (*Cell) Mixing

func (c *Cell) Mixing(Δt float64)

Mixing calculates vertical mixing based on Pleim (2007), which is combined local-nonlocal closure scheme, for boundary layer and based on Wilson (2004) for above the boundary layer. Also calculate horizontal mixing.

func (*Cell) UpwindAdvection

func (c *Cell) UpwindAdvection(Δt float64)

UpwindAdvection calculates advection in the cell based on the upwind differences scheme.

func (*Cell) WetDeposition

func (c *Cell) WetDeposition(Δt float64)

WetDeposition calculates particle removal by wet deposition

type InMAPdata

type InMAPdata struct {
	Data    []*Cell // One data holder for each grid cell
	Dt      float64 // seconds
	Nlayers int     // number of model layers

	// Number of iterations to calculate. If < 1,
	// calculate convergence automatically.
	NumIterations int

	LayerStart []int // start index of each layer (inclusive)
	LayerEnd   []int // end index of each layer (exclusive)
	// contains filtered or unexported fields

InMAPdata is holds the current state of the model.

func InitInMAPdata

func InitInMAPdata(option InitOption, numIterations int, httpPort string) (*InMAPdata, error)

InitInMAPdata initializes the model where `option` is the selected option for retrieving the input data, `numIterations` is the number of iterations to calculate (if `numIterations` < 1, convergence is calculated automatically), and `httpPort` is the port number for hosting the html GUI (if `httpPort` is "", then the GUI doesn't run).

func (*InMAPdata) CalcPlumeRise

func (d *InMAPdata) CalcPlumeRise(stackHeight, stackDiam, stackTemp,
	stackVel float64, row int) (plumeRow int, plumeHeight float64, err error)

CalcPlumeRise calculates plume rise when given stack information (see for required units) and the index of the (ground level) grid cell (called `row`). Returns the index of the cell the emissions should be added to. This function assumes that when one grid cell is above another grid cell, the upper cell is never smaller than the lower cell.

func (*InMAPdata) GetGeometry

func (d *InMAPdata) GetGeometry(layer int) []geom.T

GetGeometry returns the cell geometry for the given layer.

func (*InMAPdata) IntakeFraction

func (d *InMAPdata) IntakeFraction(
	breathingRate float64) map[string]map[string]float64

IntakeFraction calculates intake fraction from InMAP results. The input value is average breathing rate [m³/day]. The returned value is a map structure of intake fractions by pollutant and population type (map[pollutant][population]iF). This function will only give the correct results if run after InMAP finishes calculating.

func (*InMAPdata) Run

func (d *InMAPdata) Run(emissions map[string][]float64, outputAllLayers bool) (
	outputConc map[string][][]float64)

Run air quality model. Emissions are assumed to be in units of μg/s, and must only include the pollutants listed in "EmisNames". Output is in the form of map[pollutant][layer][row]concentration, in units of μg/m3. If `outputAllLayers` is true, write all of the vertical layers to the output, otherwise only output the ground-level layer.

func (*InMAPdata) VerticalProfile

func (d *InMAPdata) VerticalProfile(variable string, lon, lat float64) (
	height, vals []float64)

VerticalProfile retrieves the vertical profile for a given variable at a given location.

func (*InMAPdata) WebServer

func (d *InMAPdata) WebServer(httpPort string)

WebServer provides a HTML user interface for the model.

type InitOption

type InitOption func(*InMAPdata) error

InitOption allows options of different ways to initialize the model.

func UseCloudStorage

func UseCloudStorage(ctx context.Context, bucket string, fileNameTemplate string,
	nLayers int) InitOption

UseCloudStorage initializes the model with data from Google Cloud Storage, where ctx is the Context, `bucket` is the name of the bucket, `fileNameTemplate` is the template for the names of the Gob files with meteorology and background concentration data (where `[layer]` is a stand-in for the layer number), and `nLayers` is the number of vertical layers in the model. To minimize individual download sizes, the input files must be enclosed in zip files, with one input file per zip file. ctx must include any authentication needed for acessing the files.

func UseFileTemplate

func UseFileTemplate(filetemplate string, nLayers int) InitOption

UseFileTemplate initializes the model with data from a local disk, where `filetemplate` is the path to the Gob files with meteorology and background concentration data (where `[layer]` is a stand-in for the layer number), and `nLayers` is the number of vertical layers in the model.

func UseReaders

func UseReaders(readers []io.ReadCloser) InitOption

UseReaders initializes the model with data from `readers`, with one reader for the data for each model layer. The readers must be input in order with the ground-level data first.

func UseWebArchive

func UseWebArchive(url, fileNameTemplate string, nLayers int) InitOption

UseWebArchive initializes the model with data from a network, where `url` is the network address, `fileNameTemplate` is the template for the names of the Gob files with meteorology and background concentration data (where `[layer]` is a stand-in for the layer number), and `nLayers` is the number of vertical layers in the model. It is assumed that the input files are contained in a single zip archive.


Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL