Create with IMAS-Python¶
In this section of the training, we will have a look at creating (and filling) IDSs from scratch.
Create an empty IDS¶
Empty IDSs in IMAS-Python are created by the new()
method of an IDSFactory.
Note
New IDSs can also be created by calling IDSFactory().<ids_name>(), similar
to how new IDSs are constructed in the Access Layer.
Exercise 1¶
Create an empty core_profiles IDS.
import datetime
import imas
import numpy as np
factory = imas.IDSFactory()
cp = factory.new("core_profiles")
# Alternative
cp = factory.core_profiles()
Populate fields¶
Now we have an empty IDS, we can start filling fields. For this exercise we will populate the following fields:
ids_properties.homogeneous_time, which we will set to the constantIDS_TIME_MODE_HOMOGENEOUS. This flags that this IDS is in homogeneous time mode, meaning that all time-dependent quantities use the roottimeas their coordinate.ids_properties.comment, where we can describe this IDS.ids_properties.creation_date, which we need to set to today’s date.time = [1.0, 2.5, 4.0]profiles_1dis an array of structures, with one structure for each time slice. We need to resize it to match the size of thetimearray.For each
profiles_1dwe generate an electron temperature array and store it inprofiles_1d[index].electrons.temperature.
Exercise 2¶
Fill the core_profiles IDS with the fields as described above.
# Set properties
cp.ids_properties.homogeneous_time = imas.ids_defs.IDS_TIME_MODE_HOMOGENEOUS
cp.ids_properties.comment = "Synthetic IDS created for the IMAS-Python course"
cp.ids_properties.creation_date = datetime.date.today().isoformat()
# Set a time array
cp.time = [1.0, 2.5, 4.0]
# Main coordinate
rho_tor_norm = np.linspace(0, 1, num=64)
# Generate some 1D profiles
cp.profiles_1d.resize(len(cp.time))
for index, t in enumerate(cp.time):
t_e = np.exp(-16 * rho_tor_norm**2) + (1 - np.tanh(4 * rho_tor_norm - 3)) * t / 8
t_e *= t * 500
# Store the generated t_e as electron temperature
cp.profiles_1d[index].electrons.temperature = t_e
Note
Observe that we can assign a Python list to cp.time. IMAS-Python will
automatically convert it to a numpy array.
Sanity check the IDS¶
Before we store the IDS to disk, it is good practice to validate the IDS. When the IDS passes validation, you know that all filled quantities are consistent with their coordinates (because, what is the data worth if its coordinates are not provided?).
Exercise 3¶
Validate the just-filled IDS.
# Validate the IDS for consistency
try:
cp.validate()
print("IDS is valid!")
except imas.exception.ValidationError as exc:
print("Oops, the IDS is not valid: ", exc)
You should find that the IDS validation fails. Why?
Solution
We set the electron temperature, but we didn’t fill its coordinate rho_tor_norm!
The IDS validation reports an inconsistency between the data and coordinate size:
Dimension 1 of element `profiles_1d[0].electrons.temperature` has incorrect size
64. Expected size is 0 (size of coordinate `profiles_1d[0].grid.rho_tor_norm`).
Exercise 4¶
Fix the coordinate consistency error.
# Fill in the missing rho_tor_norm coordinate
for index in range(3):
cp.profiles_1d[index].grid.rho_tor_norm = rho_tor_norm
# And validate again
cp.validate()
Store the IDS on disk¶
Now we have created, filled and validated an IDS, the only thing left is to store it to
disk. Like loading IDSs, storing IDSs is achieved through the
DBEntry class. After constructing a DBEntry object, you
need to create() the data entry on-disk before you can
put() the IDS to disk.
Note
For this exercise we will use the ASCII backend. Although it doesn’t have the best performance or features, it is available in all builds of the Access Layer. For production usage, it is recommended to use the HDF5 or MDSplus backends.
Exercise 5¶
Store the IDS to disk.
The recommended parameters for this exercise are:
backend = imas.ids_defs.ASCII_BACKEND
database = "imas-course"
pulse = 1
run = 1
After a successful put, the ids file will be created.
this file can be found under
~/public/imasdb/imas-course/3/1/1/core_profiles.ids
Hint
The signature of DBEntry() is: DBEntry(backend, database, pulse, run)
# Create a new data entry for storing the IDS
pulse, run, database = 1, 1, "imas-course"
entry = imas.DBEntry(imas.ids_defs.ASCII_BACKEND, database, pulse, run)
entry.create()
entry.put(cp)
Summary¶
Congratulations for completing this section of the course. You have:
Created an empty
core_profilesIDSFilled some data fields of this IDS
Ensured consistency of coordinates in the IDS
Stored the newly created IDS to disk
Click on the tabs to see the complete source, combining all exercises.
import datetime
import imas
import numpy as np
factory = imas.IDSFactory()
cp = factory.new("core_profiles")
# Alternative
cp = factory.core_profiles()
# Set properties
cp.ids_properties.homogeneous_time = imas.ids_defs.IDS_TIME_MODE_HOMOGENEOUS
cp.ids_properties.comment = "Synthetic IDS created for the IMAS-Python course"
cp.ids_properties.creation_date = datetime.date.today().isoformat()
# Set a time array
cp.time = [1.0, 2.5, 4.0]
# Main coordinate
rho_tor_norm = np.linspace(0, 1, num=64)
# Generate some 1D profiles
cp.profiles_1d.resize(len(cp.time))
for index, t in enumerate(cp.time):
t_e = np.exp(-16 * rho_tor_norm**2) + (1 - np.tanh(4 * rho_tor_norm - 3)) * t / 8
t_e *= t * 500
# Store the generated t_e as electron temperature
cp.profiles_1d[index].electrons.temperature = t_e
# Validate the IDS for consistency
try:
cp.validate()
print("IDS is valid!")
except imas.exception.ValidationError as exc:
print("Oops, the IDS is not valid: ", exc)
# Fill in the missing rho_tor_norm coordinate
for index in range(3):
cp.profiles_1d[index].grid.rho_tor_norm = rho_tor_norm
# And validate again
cp.validate()
# Create a new data entry for storing the IDS
pulse, run, database = 1, 1, "imas-course"
entry = imas.DBEntry(imas.ids_defs.ASCII_BACKEND, database, pulse, run)
entry.create()
entry.put(cp)