Exploring results

Running the model using the client returns a ModelRun python class/object.

ModelRun objects

A ModelRun contains the following information/data:

  • One or more ModelResult classes/objects. These contain the actual model results.
  • Run statuses and messages.
  • Unique run ID.
  • Run datetime (ISO format)
  • The RunContext

The ModelRun class is also a dictionary with the dictionary keys being the names of the models.

sapre_results = nom_client.run_model(model=sapre_model)
>>> ['trajectory', 'attitude_vectors']
>>> dict_keys(['trajectory', 'attitude_vectors'])

The model results contained within the ModelRun object correspond to the results defined within the outputs section of the model specification.

ModelResult objects
Run the SAPPHIRE Total Fluence model
sapre_model = nom_client.get_model(model_name="sapre")
sapre_result = nom_client.run_model(model=sapre_model)

sapphire_model = nom_client.get_model(model_name="sapphire-total-fluence")
sapphire_model.set_external_input(external_input_name="trajectory", external_input=sapre_result)
sapphire_result = nom_client.run_model(model=sapphire_model)


The result object 'ae8ap8_result' is an instance of a 'ModelRun' class AND also a dictionary of 'ModelResult' classes.

# Or get the result names from the result object
>>> ['sep_proton_spectrum', 'full_ion_spectrum']

# Or list the keys of the results dictionary
>>> dict_keys(['sep_proton_spectrum', 'full_ion_spectrum'])

# Loop over the model results
for result_name, result in sapphire_result.items():

>>> ModelResult: sep_proton_spectrum, quantity=energy_fluence_spectrum, variables=[energy, integral_fluence, differential_fluence, Attenuation, Exposure]
>>> ModelResult: full_ion_spectrum, quantity=energy_fluence_spectrum, variables=[energy, species, integral_fluence, differential_fluence]

# Lets take a look at the 'full_ion_spectrum' result

# Get the result using the 'get_model_result_by_name' method
full_ion_spectrum = sapphire_result.get_model_result_by_name(result_name="full_ion_spectrum")
>>> ModelResult: full_ion_spectrum, quantity=energy_fluence_spectrum, variables=[energy, species, integral_fluence, differential_fluence]

# ... or access the result directly
full_ion_spectrum = sapphire_result["full_ion_spectrum"]
>>> ModelResult: full_ion_spectrum, quantity=energy_fluence_spectrum, variables=[energy, species, integral_fluence, differential_fluence]

# Lets list the variables within the 'orbit_averaged_proton_spectrum' result.
>>> ['energy', 'species', 'integral_fluence', 'differential_fluence']

# Loop over the variables
print("\n--- Loop over the variables in the 'orbit_averaged_proton_spectrum' result' ---")
for variable_name, variable in full_ion_spectrum.items():

>>> Variable: energy, dim: 1
>>> Variable: species, dim: 1
>>> Variable: integral_fluence(energy,species), dim: 2
>>> Variable: differential_fluence(energy,species), dim: 2

# Loop over the variables
energy_variable = full_ion_spectrum['energy']
species_variable = full_ion_spectrum['species']
integral_fluence_variable = full_ion_spectrum['integral_fluence']

Looking at the details of the variables using 'get_metadata()'

'energy' is row-varying with a dimensionality of {'cols': 1, 'rows': 81}
'species' is column varying (not row-varying) with a dimensionality of {'cols': 92, 'rows': 1}
'integral_fluence' is row-varying with a dimensionality of {'cols': 92, 'rows': 81}

>>> {
>>>   'axes': {},
>>>   'description': '',
>>>   'dimensionality': {'cols': 1, 'rows': 81},
>>>   'name': 'energy',
>>>   'qualifiers': {},
>>>   'quantity': 'energy',
>>>   'row_varying': True,
>>>   'units': 'MeV/n',
>>>   'valid_max': None,
>>>   'valid_min': None
>>> }

>>>   'axes': {},
>>>   'description': 'Uncategorised number',
>>>   'dimensionality': {'cols': 1, 'rows': 92},
>>>   'name': 'species',
>>>   'qualifiers': {},
>>>   'quantity': 'number',
>>>   'row_varying': False,
>>>   'units': '1',
>>>   'valid_max': None,
>>>   'valid_min': None

>>>   'axes': {1: 'energy', 2: 'species'},
>>>   'description': '',
>>>   'dimensionality': {'cols': 92, 'rows': 81},
>>>   'name': 'integral_fluence',
>>>   'qualifiers': {'direction': 'omni-directional',
>>>               'form': 'integral',
>>>               'period': 'mission',
>>>               'species': 'multiple'},
>>>   'quantity': 'number_fluence',
>>>   'row_varying': True,
>>>   'units': 'cm^-2',
>>>   'valid_max': None,
>>>   'valid_min': None

# To get the actual data values we use the model result object method 'get_variable_data'
# To get the entire 'integral_fluence' dataset, energy vs. species

integral_fluence_data = full_ion_spectrum.get_variable_data(variable_name="integral_fluence")
>>> [['H' 'He' 'Li' 'Be' 'B' 'C' 'N' 'O' 'F' 'Ne' 'Na' 'Mg' 'Al' 'Si' 'P' 'S'
  'Cl' 'Ar' 'K' 'Ca' 'Sc' 'Ti' 'V' 'Cr' 'Mn' 'Fe' 'Co' 'Ni' 'Cu' 'Zn'
  'Ga' 'Ge' 'As' 'Se' 'Br' 'Kr' 'Rb' 'Sr' 'Y' 'Zr' 'Nb' 'Mo' 'Tc' 'Ru'
  'Rh' 'Pd' 'Ag' 'Cd' 'In' 'Sn' 'Sb' 'Te' 'I' 'Xe' 'Cs' 'Ba' 'La' 'Ce'
  'Pr' 'Nd' 'Pm' 'Sm' 'Eu' 'Gd' 'Tb' 'Dy' 'Ho' 'Er' 'Tm' 'Yb' 'Lu' 'Hf'
  'Ta' 'W' 'Re' 'Os' 'Ir' 'Pt' 'Au' 'Hg' 'Tl' 'Pb' 'Bi' 'Po' 'At' 'Rn'
  'Fr' 'Ra' 'Ac' 'Th' 'Pa' 'U']]

You can get more specific data by supplying additional parameters, in the case of 'integral fluence' 
we can specify any of its axes values, i.e. 'energy' or 'species'

We can print out the values for 'species' and then slice the fluence data further into a vector of values over energy
species_data = full_ion_spectrum.get_variable_data(variable_name="species")
>>> [[6.1951e+11 5.8858e+11 5.6138e+11 5.1551e+11 4.7811e+11 4.4686e+11
  4.2023e+11 3.9720e+11 3.6781e+11 3.4316e+11 3.1575e+11 2.9832e+11
  2.7370e+11 2.5331e+11 2.3607e+11 2.2127e+11 2.0142e+11 1.8512e+11
  1.6990e+11 1.5585e+11 1.4407e+11 1.3404e+11 1.2538e+11 1.1114e+11
  9.9898e+10 9.0777e+10 8.3218e+10 7.6847e+10 6.8964e+10 6.2577e+10
  5.5672e+10 5.1359e+10 4.5377e+10 4.0509e+10 3.6457e+10 3.3020e+10
  2.8509e+10 2.4952e+10 2.1791e+10 1.9008e+10 1.6748e+10 1.4865e+10
  1.3268e+10 1.0714e+10 8.7679e+09 7.2367e+09 6.0307e+09 5.0863e+09
  4.0098e+09 3.2114e+09 2.4288e+09 1.9852e+09 1.4345e+09 1.0533e+09
  7.8499e+08 5.8949e+08 3.8796e+08 2.7265e+08 1.9559e+08 1.4324e+08
  1.0945e+08 8.6678e+07 7.0609e+07 4.9517e+07 3.6665e+07 2.8214e+07
  2.2260e+07 1.7888e+07 1.3251e+07 1.0101e+07 7.2986e+06 5.8477e+06
  4.1775e+06 3.0830e+06 2.3336e+06 1.8022e+06 1.2306e+06 8.6509e+05
  6.0072e+05 4.1624e+05 2.9796e+05]]

# Get integral fluence data for species 'H'
species_data_H = full_ion_spectrum.get_variable_data(variable_name="integral_fluence", species="H")
print("\n--- species data (species: H)---\n")

Similarly we can specify an energy to reduce our vector of data to a scalar value
energy_data = full_ion_spectrum.get_variable_data(variable_name="energy")
>>> [[1.0e-01 1.1e-01 1.2e-01 1.4e-01 1.6e-01 1.8e-01 2.0e-01 2.2e-01 2.5e-01
  2.8e-01 3.2e-01 3.5e-01 4.0e-01 4.5e-01 5.0e-01 5.5e-01 6.3e-01 7.1e-01
  8.0e-01 9.0e-01 1.0e+00 1.1e+00 1.2e+00 1.4e+00 1.6e+00 1.8e+00 2.0e+00
  2.2e+00 2.5e+00 2.8e+00 3.2e+00 3.5e+00 4.0e+00 4.5e+00 5.0e+00 5.5e+00
  6.3e+00 7.1e+00 8.0e+00 9.0e+00 1.0e+01 1.1e+01 1.2e+01 1.4e+01 1.6e+01
  1.8e+01 2.0e+01 2.2e+01 2.5e+01 2.8e+01 3.2e+01 3.5e+01 4.0e+01 4.5e+01
  5.0e+01 5.5e+01 6.3e+01 7.1e+01 8.0e+01 9.0e+01 1.0e+02 1.1e+02 1.2e+02
  1.4e+02 1.6e+02 1.8e+02 2.0e+02 2.2e+02 2.5e+02 2.8e+02 3.2e+02 3.5e+02
  4.0e+02 4.5e+02 5.0e+02 5.5e+02 6.3e+02 7.1e+02 8.0e+02 9.0e+02 1.0e+03]]

species_data_H_e = full_ion_spectrum.get_variable_data(variable_name="integral_fluence", species="H", energy=1.0e-01)
>>> [[6.1951e+11]]

Access to this repository can be requested by emailing space-env@esa.int