MAGICC flags¶
This section describes some of the (magical) flags contained in MAGICC and the gotchas which we have discovered so far. If you have an issue, please raise it in the issue tracker and we will do our best to assist you before documenting the solution here.
Before moving on, note that Fortran is a case-insensitive language. Thus you shouldn’t
worry if you see a flag written as MAGICC_FLAG
, magicc_flag
or MagICC_FlAg
.
In Pymagicc, the f90nml
package takes care of this case-insensitivity for us.
Conventions¶
MAGICC’s flags have a few repeating conventions which can make them easier to understand. However, sometimes the naming convention conflicts with the behaviour so it’s worth double checking if in doubt. Here we summarise a few key conventions:
endings like
0NO1SCALE2SHIFT
: in general, if these flags are set to0
then they will do nothing, if set to1
they will adjust the ‘input’ series to ‘target’ series by scaling (i.e. multiplying the whole series by a constant) and if set to2
they will adjust the input series to the target series by shifting (i.e. adding/subtracting a constant to the whole series).ABC_NAMES
: defines the variable names which belong to the group which will commonly be referred to with a prefix ofABC
e.g.FGAS_NAMES
: defines the F-gases in MAGICC.ABC_SWITCHFROMCONC2EMIS_YEAR
: the year in which to switch from being concentration driven to emissions driven for the gas/group of gasesABC
e.g.CO2_SWITCHFROMCONC2EMIS_YEAR
defines the year in which to switch from being CO2 concentration driven to CO2 emissions driven.
Undocumented flags¶
In the MAGICC6 binary shipped with Pymagicc, all flags are contained in
MAGCFG_DEFAULTALL_69.CFG
. Hence they are in some sense ‘documented’ and at least it
is obvious where to look in order to see what all the possible options are.
In MAGICC7, this isn’t always the case. Hence, here we provide a list of flags which
are not in MAGCFG_DEFAULTALL.CFG
but are nonetheless valid and useable.
FGAS_ADJSTFUTREMIS2PAST_0NO1SCALE
: adjust future F-gas emissions to past emissions.MHALO_ADJSTFUTREMIS2PAST_0NO1SCALE
: adjust future Montreal Protocol halogen emissions to past emissions.
Configuration flags¶
When you run MAGICC, you have a series of .CFG
files which set parameter values.
The first two are always (and must be) MAGCFG_DEFAULTALL.CFG
and
MAGCFG_USER.CFG
. Exception: in the compiled binary that is shipped with
Pymagicc, the file it looks for is MAGCFG_DEFAULTALL_69.CFG
, not
MAGCFG_DEFAULTALL.CFG
.
After these two compulsory files, you can then specify extra .CFG
files. Each of
these .CFG
files is specified in FILE_TUNINGMODEL_X
flags.
Gotcha: say you have FILE_TUNINGMODEL_X=ABCD
, MAGICC will look for
MAGTUNE_ABCD.CFG
. Note that MAGICC will not look for ABCD
or ABCD.CFG
.
Hence if we have FILE_TUNINGMODEL_8=PYMAGICC
, then the 8th tuning file MAGICC will
look for will be MAGTUNE_PYMAGICC.CFG
. This is why we write the configuration to
MAGTUNE_PYMAGICC.CFG
but have FILE_TUNINGMODEL_X=PYMAGICC
.
Gotcha: if FILE_TUNINGMODEL_X
is set to USER
, MAGICC won’t look for any
configuration file at all and will simply just move to the next FILE_TUNINGMODEL_X
flag. I think the rationale here is that you have to read MAGCFG_USER.CFG
(see
above) and hence using this flag as a “don’t read” flag is safe. Fortunately if you
set FILE_TUNINGMODEL_X
to an empty string i.e. “” then MAGICC will also skip that
.CFG
file so there is a safer and more obvious option.
Gotcha: the first flag MAGICC6 looks at is FILE_TUNING_MODEL
, without any number, whilst the rest are all of the form FILE_TUNINGMODEL_X
where X is a positive integer (i.e. not zero).
Gotcha: the convention above changes in MAGICC7, where FILE_TUNINGMODEL
is replaced by FILE_TUNINGMODEL_1
.
Gotcha: the maximum value of X
in FILE_TUNINGMODEL_X
varies depending on
your binary and there’s no way to query the binary except for just trying higher and
higher X
until it fails.
Gotcha: each .CFG
file contains a set of parameters, each of which overwrites
any previously read parameter values. i.e. the file pointed to by
FILE_TUNINGMODEL_4
overwrites flags set by FILE_TUNINGMODEL_3
etc. However,
each .CFG
file can contain FILE_TUNINGMODEL_X
flags itself. Hence you could
have the following situation:
MAGCFG_DEFAULTALL.CFG
setsFILE_TUNINGMODEL=USER
andFILE_TUNINGMODEL_X=USER
for allX
i.e. no overwrites on top of what will be read fromMAGCFG_DEFAULTALL.CFG
andMAGCFG_USER.CFG
MAGCFG_USER.CFG
sets e.g.FILE_TUNINGMODEL=ZNEXAMPLE
andFILE_TUNINGMODEL_2=PYMAGICC
, leaving everything else untouchedhence at this point we would expect MAGICC to read in
MAGCFG_DEFAULTALL.CFG
, then overwrite its values with values inMAGCFG_USER.CFG
, then overwrite those values with values inMAGTUNE_ZNEXAMPLE.CFG
, finally overwriting those values with the values inMAGTUNE_PYMAGICC.CFG
MAGTUNE_ZNEXAMPLE.CFG
setsFILE_TUNINGMODEL_2=USER
now
MAGTUNE_PYMAGICC.CFG
won’t be read at all, destroying our previous impression
An even more confusing situation is this one:
MAGCFG_DEFAULTALL.CFG`
setsFILE_TUNINGMODEL=USER
andFILE_TUNINGMODEL_X=USER
for all X i.e. no overwrites on top of what will be read fromMAGCFG_DEFAULTALL.CFG
andMAGCFG_USER.CFG
MAGCFG_USER.CFG
sets e.g.FILE_TUNINGMODEL=ZNEXAMPLE
,FILE_TUNINGMODEL_2=RGEX
andFILE_TUNINGMODEL_3=PYMAGICC
, leaving everything else untouchedhence at this point we would expect MAGICC to read in
MAGCFG_DEFAULTALL.CFG
, then overwrite its values with values inMAGCFG_USER.CFG
, then overwrite those values with values inMAGTUNE_ZNEXAMPLE.CFG`
, then overwrite those values with values inMAGTUNE_RGEX.CFG
, finally overwriting those values with the values inMAGTUNE_PYMAGICC.CFG
MAGTUNE_ZNEXAMPLE.CFG
contains noFILE_TUNINGMODEL_X
flags i.e. doesn’t change things from our previous expecationsMAGTUNE_RGEX.CFG
setsFILE_TUNINGMODEL=USER
andFILE_TUNINGMODEL_2=USER
.Intuitively, we would expect this to mean that
MAGTUNE_ZNEXAMPLE.CFG
andMAGTUNE_RGEX.CFG
will no longer be read, but actually what will happen is that nothing will change. This is because, whenMAGTUNE_RGEX.CFG
is read in, it is read in after MAGICC has already looked at the value of theFILE_TUNINGMODEL
andFILE_TUNINGMODEL_2
flags and hence altering this flag, at the point in time whenMAGTUNE_RGEX.CFG
is read in, won’t have any futher effect.
Finally one more example:
MAGCFG_DEFAULTALL.CFG`
setsFILE_TUNINGMODEL=USER
andFILE_TUNINGMODEL_X=USER
for all X i.e. no overwrites on top of what will be read fromMAGCFG_DEFAULTALL.CFG
andMAGCFG_USER.CFG
MAGCFG_USER.CFG
sets e.g.FILE_TUNINGMODEL=ZNEXAMPLE
,FILE_TUNINGMODEL_2=RGEX
andFILE_TUNINGMODEL_3=PYMAGICC
, leaving everything else untouchedhence at this point we would expect MAGICC to read in
MAGCFG_DEFAULTALL.CFG
, then overwrite its values with values inMAGCFG_USER.CFG
, then overwrite those values with values inMAGTUNE_ZNEXAMPLE.CFG`
, then overwrite those values with values inMAGTUNE_RGEX.CFG
, finally overwriting those values with the values inMAGTUNE_PYMAGICC.CFG
MAGTUNE_ZNEXAMPLE.CFG
containsFILE_TUNINGMODEL_X=""
for allX
this means that MAGICC will skip reading any more tuning files and hence
MAGTUNE_RGEX.CFG
will not be read
The reason this is confusing/annoying is that you have to read, and carefully trace,
the hierarchy of every single .CFG
file in order to work out what is going to
happen. The easier option is to run MAGICC and then just see what comes through in
run/PARAMETERS.OUT
. To help this, there are two small functions in pymagicc.io
,
namely pull_cfg_from_parameters_out_file
and pull_cfg_from_parameters_out
.
An outline of a function which could do this a priori (i.e. by reading the .CFG
files) might look something like this:
from os.path import join, isfile
import f90nml
def get_magicc_search_file(base):
return "MAGTUNE_{}.CFG".format(base)
def valid_search_model(base):
return ((base != "") and (base != "USER"))
def update_cfg_from_tuningmodel_like_magicc(cfg, tuningmodel):
if valid_search_model(tuningmodel):
cfg.update(f90nml.read(join(
run_dir,
get_magicc_search_file(tuningmodel)
)))
return cfg
def derive_final_cfg(run_dir, namelist_to_derive):
try:
cfg = f90nml.read(join(run_dir, "MAGCFG_DEFAULTALL.CFG"))
except FileNotFoundError:
cfg = f90nml.read(join(run_dir, "MAGCFG_DEFAULTALL_69.CFG"))
cfg.update(f90nml.read(join(run_dir, "MAGCFG_USER.CFG")))
# f90nml reads lowercase by default
if "file_tuningmodel" in cfg[namelist_to_derive]:
cfg = update_cfg_from_tuningmodel_like_magicc(
cfg,
cfg[namelist_to_derive]["file_tuningmodel"]
)
elif "file_tuningmodel_1" in cfg:
cfg = update_cfg_from_tuningmodel_like_magicc(
cfg,
cfg[namelist_to_derive]["file_tuningmodel_1"]
)
for i in range(2, 50):
key_to_check = "file_tuningmodel_{}".format(i)
if key in cfg[namelist_to_derive]:
cfg = update_cfg_from_tuningmodel_like_magicc(
cfg,
cfg[namelist_to_derive][key]
)
return cfg
# Example usage
run_dir = "/here/there/MAGICC/run"
namelist_to_derive = "all_cfgs"
output_file = "./somewhere/else/example.cfg"
derive_final_cfg(run_dir, namelist_to_derive).write(output_file)
To avoid any really unexpected, silent surprises, we want the pymagicc .CFG
file,
MAGTUNE_PYMAGICC.CFG
to overwrite everything else. To save trying to debug
extremely tricky overwriting setups, we enforce simple configurations in Pymagicc and
raise ValueError
if they are not adhered to.
Clash with scenario flags¶
These ‘conventions’ become more confusing when we compare to what happens with the emission scenario files.
In MAGICC6 it’s simple, there’s only one emissions scenario file and it goes in
FILE_EMISSIONSCENARIO=DFGH
. MAGICC then looks for files that match DFGH
and
DFGH.SCEN
.
In MAGICC7, there are now multiple FILE_EMISSCEN_X
flags (note the shift from
FILE_EMISSIONSCENARIO
). The values found in the file specified in each
FILE_EMISSCEN_X
flag overwrite any previously read in values.
Gotcha: The first emissions scenario file is specified by FILE_EMISSCEN
(without
the number), which matches the MAGICC6 convention for FILE_TUNINGMODEL
but
contradicts the MAGICC7 convention for FILE_TUNINGMODEL
.
Gotcha: Say we have FILE_EMISSCEN=DFGH
, MAGICC7 looks for files that match
DFGH
, then DFGH.SCEN7
and then DFGH.SCEN
(in that order). Hence the first
emissions scenario can be SCEN7, or SCEN, with preference being given to SCEN7 files
if there are two scenario files with the same stem (i.e. RCP26.SCEN7
is chosen
before RCP26.SCEN
if FILE_EMISSCEN=RCP26
).
Gotcha: In MAGICC7, only the first FILE_EMISSCEN
can be a SCEN
file (in
MAGICC6 there can only be SCEN
files so this isn’t an issue). All other
FILE_EMISSCEN_X
files can only be SCEN7 files. The rationale here (I think) is
that SCEN files don’t contain easy to read metadata hence overwriting with them is
difficult/dangerous.
Gotcha: If the scenario file has a region mode other than World, all World region data are ignored. This means that all emissions cannot be currently stored in a single SCEN7 file as MHalo data is only provided as a single World region, while most other species are disaggregated by region.
Gotcha: If you set FILE_EMISSCEN_X=NONE
then MAGICC will just move on to the
next FILE_EMISSCEN_X
flag. However, from above it’s clear that if you set
FILE_TUNINGMODEL_X=NONE
, MAGICC will look for MAGTUNE_NONE.CFG
, not find it
and blow up. Hence there’s a direct contradiction there too.
Gotcha: Of course the final part is that each .CFG
file can overwrite the
FILE_EMISSCEN_X
flags of previous .CFG
hence working out which scenario will actually be run is also not trivial.