Create a basic SPEX Fortran program¶
The new SPEX API enables the use of SPEX within a Fortran program through direct calls to the SPEX subroutines. To make this easy, the subroutine names are very similar to their command-line counterparts.
In this quick tutorial, we will show how to include SPEX in a Fortran program and how compile it.
Note
If you need to run SPEX command-line commands from Fortran, then look into the spex_session module.
Creating a Fortran program¶
For this exercise, create a text file called lines.f90 in an
empty directory. This will be our test program to generate a line list
for a specific ion in a thermal plasma.
Open the file lines.f90 and copy the following lines into it:
program lines ! Defines that this is a Fortran program
use spex_api ! We will use the SPEX Fortran API
type(sapi) :: spex ! We create a special variable called spex that will be our link to the API
call spex%init() ! Calling the init routine of the SPEX API initializes SPEX
call spex%final() ! Calling the final routine closes SPEX at the end of the program
end program
The program above is the most basic setup to use SPEX in a Fortran program.
The spex variable is of type sapi, which means it contains the SPEX
API object with all the SPEX API subroutines.
SPEX can be started in the program by calling spex%init(). This subroutine
loads all the SPEX data in memory and should be called first.
At the end of the program, SPEX needs to be unloaded again by calling
spex%final(), which deallocates all memory systematically. The program
is closed by the end program statement.
Checking the SPEX environment¶
Save the lines.f90 text file and exit the editor. For compiling the code,
you need to have a Fortran compiler installed, like gfortran. See
these Fortran install hints
for more information.
Before you can compile the code, you need to make sure that SPEX is sourced
(i.e. its important locations need to be loaded into the terminal). If the
command echo $SPEX4 results in an empty line, SPEX is not sourced yet.
If you see the path to the SPEX4 installation, you can skip this step.
We assume here that SPEX4 is installed in /opt/spex4/, but please
change it to your install location. To source SPEX, type:
$ source /opt/spex4/spexdist.sh
The command echo $SPEX4 should now show the path to your SPEX installation.
Compiling the code¶
Once the environment is set up, we can compile the lines program. In the terminal, give the command below to compile it:
$ gfortran -o lines -I$SPEX4/modules -L$SPEX4/lib -lspex lines.f90
The -o lines flag tells gfortran to create an executable called lines.
The -I$SPEX4/modules tells gfortran to look for the module descriptions in the
SPEX modules directory. This is used by the compiler to check your code for
errors. The -L$SPEX4/lib -lspex flags tell the compiler to link the library
libspex from the $SPEX4/lib directory to the program. This makes sure
that the lines program can find SPEX.
The command above should result in an executable called lines. You can run
it in the terminal with:
$ ./lines
Welcome user to SPEX version 3.99.00
NEW in this version of SPEX:
Setting the number of threads to 4 for optimal performance.
Now using SPEXATOM version 2.07.00
You will see that the lines executable starts SPEX and closes it again.
Expanding the program¶
Obviously, you would like to do more with the program than only loading and
closing SPEX. In between the call spex%init() and call spex%final() lines,
you can add as many statements as you need. You can add variables, call SPEX API
subroutines and add other Fortran code.
As an example, let us create a program to output a line list for a given ion. Let us expand the program that we had before:
program lines
use spex_api
!
! We add variable definitions to this section
!
type(sapi) :: spex
integer :: ier ! Add an integer variable called ier to store error codes
! Define variables for the input parameters
integer :: z ! Atomic number of the element
integer :: ion ! Ionisation stage of the ion
real :: kt ! Temperature in keV of the plasma
character*4:: atype ! Type of ascii output
call spex%init()
!
! We add new SPEX function calls to this section
!
call spex%comp('cie',1,1,ier) ! We add a 'cie' component in sector number 1
! (the two ones stand for the start and end sector to create a 'cie')
! This is equivalent to the SPEX command `com cie`
call spex%var_calc('new',ier) ! Use the new line database ('var calc new')
! Gather input from the user
write (*,'(" Please enter the atomic number of the element: ")', advance="NO")
read (*,*) z
write (*,'(" Please enter the ionisation stage of the ion: ")', advance="NO")
read (*,*) ion
write (*,'(" Please enter the temperature of the plasma: ")', advance="NO")
read (*,*) kt
! We select the ion using the ions commands:
call spex%ions_ignore_all(ier) ! Ignore all ions
call spex%ions_use_ion(z,ion,ier) ! Use ion with atomic number 'z' and stage 'ion'
! We set the temperature using the par command:
call spex%par_set_value(1,1,'t',kt,ier)
! We print the line list to the terminal
atype = 'line'
call spex%ascdump_ter(1,1,atype,ier)
call spex%final()
end program
The program above asks the user for an atomic number, an ionisation stage (number), and a temperature in keV. It sets the new atomic database and then shows the lines for the ion in the terminal.
This is a basic example, but through the calls to SPEX, also values can be collected that you can use to adapt the flow in your program. You can, for example, test the c-statistics value and determine whether a fit needs to be run again. This will be explained in separate analysis threads.