# Importing results from a GAMS model to an IamDataFrame¶

This tutorial illustrates how to extract results from any GAMS model (via the gdx file) and cast them to an **IamDataFrame** for further processing.

The workflow presented here uses the **GAMS Python API** (read the docs) and the **gamstransfer** module.

Follow these steps to install the requirements:

Manually install the GAMS API, follow one of the options in this description.

**TL;DR**: search for the folder “api_38” in the GAMS installation folder on your machine and runpython setup.py install

Install the

**schema**package viapip install schema

This is a dependency of the

**gamstransfer**module.

This notebook was run with Python 3.8 and GAMS 33.2 on Mac OS.

**Developers note:**Running this notebook on CI and RTD is a challenge due to the need to download and install the GAMS API.

**nbsphinx**and has to be saved with output.

## The transport model¶

The model used for this illustration is the transport model by Rosenthal, frequently used for tutorials and examples.

The complete model is repeated here for clarity - note the last line which exports the results to a file in the GAMS Data Exchange (gdx) format.

```
*Basic example of transport model from GAMS model library
$Title A Transportation Problem (TRNSPORT,SEQ=1)
$Ontext
This problem finds a least cost shipping schedule that meets
requirements at markets and supplies at factories.
Dantzig, G B, Chapter 3.3. In Linear Programming and Extensions.
Princeton University Press, Princeton, New Jersey, 1963.
This formulation is described in detail in:
Rosenthal, R E, Chapter 2: A GAMS Tutorial. In GAMS: A User's Guide.
The Scientific Press, Redwood City, California, 1988.
$Offtext
Sets
i canning plants / seattle, san-diego /
j markets / new-york, chicago, topeka / ;
Parameters
a(i) capacity of plant i in cases
/ seattle 350
san-diego 600 /
b(j) demand at market j in cases
/ new-york 325
chicago 300
topeka 275 / ;
Table d(i,j) distance in thousands of miles
new-york chicago topeka
seattle 2.5 1.7 1.8
san-diego 2.5 1.8 1.4 ;
Scalar f freight in dollars per case per thousand miles /90/ ;
Parameter c(i,j) transport cost in thousands of dollars per case ;
c(i,j) = f * d(i,j) / 1000 ;
Variables
x(i,j) shipment quantities in cases
z total transportation costs in thousands of dollars ;
Positive Variable x ;
Equations
cost define objective function
supply(i) observe supply limit at plant i
demand(j) satisfy demand at market j ;
cost .. z =e= sum((i,j), c(i,j)*x(i,j)) ;
supply(i) .. sum(j, x(i,j)) =l= a(i) ;
demand(j) .. sum(i, x(i,j)) =g= b(j) ;
Model transport /all/ ;
Solve transport using lp minimizing z ;
Display x.l, x.m ;
Execute_unload 'transport_tutorial.gdx';
```

## Import results from the gdx file¶

The first cell imports **pyam** and the two GAMS packages used in this tutorial.

```
[2]:
```

```
from gams import GamsWorkspace
from gamstransfer import GdxContainer
gdx = GdxContainer(GamsWorkspace().system_directory, "transport_tutorial.gdx")
gdx.rgdx()
```

## Cast results to an IamDataFrame¶

The first cell in this section defines the model and scenario identifiers, which are identical for all results.

```
[3]:
```

```
args = dict(model="transport", scenario="baseline")
```

**IamDataFrame**requires some information on the time domain.

### The objective value¶

The first cell in this section reads the value of the objective function, adds the year and displays the data.

**IamDataFrame**using the variable name

`cost`

.The last cell displays the data of the **IamDataFrame**.

```
[4]:
```

```
z = gdx.to_dataframe("z")["elements"]
z["year"] = 2020
z
```

```
[4]:
```

L | year | |
---|---|---|

0 | 153.675 | 2020 |

```
[5]:
```

```
from pyam import IamDataFrame
df = IamDataFrame(z, variable="cost", region="USA", unit="$", value="L", **args)
```

```
[6]:
```

```
df.timeseries()
```

```
[6]:
```

2020 | |||||
---|---|---|---|---|---|

model | scenario | region | variable | unit | |

transport | baseline | USA | cost | $ | 153.675 |

### Optimal shipment of quantities¶

`x`

.`L`

) is read by default by the **GdxContainer.to_dataframe()**function.

```
[7]:
```

```
x = gdx.to_dataframe("x")["elements"]
x["year"] = 2020
x
```

```
[7]:
```

i | j | L | year | |
---|---|---|---|---|

0 | seattle | new-york | 50.0 | 2020 |

1 | seattle | chicago | 300.0 | 2020 |

2 | seattle | topeka | 0.0 | 2020 |

3 | san-diego | new-york | 275.0 | 2020 |

4 | san-diego | chicago | 0.0 | 2020 |

5 | san-diego | topeka | 275.0 | 2020 |

There are several ways to coerce the “from-to” dimension of the mathematical formulation to the “variable/region” format used in the IAMC data standard. In this example, we define a variable `supply|*`

where * is the supply location and we use the demand center as the region.

This is implemented by adding a column ‘type’ to the shipment-dataframe and appending a new object to the results **IamDataFrame** concatening the ‘type’ column and the origin column ‘i’.

```
[8]:
```

```
x["type"] = "supply"
```

```
[9]:
```

```
df.append(
x, variable=["type", "i"], value="L", region="j", unit="cases", **args, inplace=True
)
```

### Market prices at the demand centers¶

The `market price`

can be determined from the marginal value (field: `M`

) of the demand-constraint equations.

```
[10]:
```

```
demand = gdx.to_dataframe("demand", fields="M")["elements"]
demand["year"] = 2020
demand
```

```
[10]:
```

j | M | year | |
---|---|---|---|

0 | new-york | 0.225 | 2020 |

1 | chicago | 0.153 | 2020 |

2 | topeka | 0.126 | 2020 |

```
[11]:
```

```
df.append(
demand,
variable="market price",
value="M",
region="j",
unit="$/case",
**args,
inplace=True,
)
```

```
[12]:
```

```
df.timeseries()
```

```
[12]:
```

2020 | |||||
---|---|---|---|---|---|

model | scenario | region | variable | unit | |

transport | baseline | USA | cost | $ | 153.675 |

chicago | market price | $/case | 0.153 | ||

supply|san-diego | cases | 0.000 | |||

supply|seattle | cases | 300.000 | |||

new-york | market price | $/case | 0.225 | ||

supply|san-diego | cases | 275.000 | |||

supply|seattle | cases | 50.000 | |||

topeka | market price | $/case | 0.126 | ||

supply|san-diego | cases | 275.000 | |||

supply|seattle | cases | 0.000 |

## Postprocessing to compute aggregate results¶

It is often practical to not only have results at the most disaggregated level, but to also add aggregated results to the output. The **pyam** package offers several utilities to perform aggregation or validation; the following cell computes the total supply to each demand city and appends it to the **IamDataFrame**.

The second cell again displays the complete data to illustrate the aggregation feature.

```
[13]:
```

```
df.aggregate("supply", append=True)
```

```
[14]:
```

```
df.timeseries()
```

```
[14]:
```

2020 | |||||
---|---|---|---|---|---|

model | scenario | region | variable | unit | |

transport | baseline | USA | cost | $ | 153.675 |

chicago | market price | $/case | 0.153 | ||

supply | cases | 300.000 | |||

supply|san-diego | cases | 0.000 | |||

supply|seattle | cases | 300.000 | |||

new-york | market price | $/case | 0.225 | ||

supply | cases | 325.000 | |||

supply|san-diego | cases | 275.000 | |||

supply|seattle | cases | 50.000 | |||

topeka | market price | $/case | 0.126 | ||

supply | cases | 275.000 | |||

supply|san-diego | cases | 275.000 | |||

supply|seattle | cases | 0.000 |

## Visualization of results¶

The **pyam** package includes a powerful plotting and visualization library. Most features are geared for timeseries data (for plotting development over time), but some are useful even for this small, stylized application: the next cell shows the regional share of supply from the two supply locations to the three demand centers.

```
[15]:
```

```
df.filter(variable="supply|*").plot.bar(x="region")
```

```
[15]:
```

```
<AxesSubplot:title={'center':'model: transport scenario: baseline'}, xlabel='Region', ylabel='cases'>
```

Visit the **pyam** plotting gallery for more features and options!

## Exporting to different file formats¶

You can use **pyam** to export the processed data in the IAMC format as an Excel table.

```
[16]:
```

```
df.to_excel("transport.xlsx")
```

**pyam** also supports export to different file formats, for example the frictionless data package!

```
[17]:
```

```
df.to_datapackage("transport.zip")
```

```
[17]:
```

```
<datapackage.package.Package at 0x7fd68e73d970>
```

**Questions?** Take a look at this tutorial for *first steps with pyam* - then join our mailing list!