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.