.. SPDX-FileCopyrightText: 1992-2026 NWO-I/SRON Space Research Organisation Netherlands .. .. SPDX-License-Identifier: CC-BY-4.0 .. _spexapi_model: Model related procedures ======================== A SPEX model is organised in sectors and components. Sectors are groups of components that model a particular source of radiation. Below, the basic commands for building the model and change its parameters are listed. .. _spexapi_abun: Abundance --------- The solar abundance table used is set in SPEX using the ``abundance`` command. The desired abundance table should be loaded by providing the abbreviation for the table (``abunset``):: call spex%abundance(abun,ier) The possible abundance tables are: * ``reset``: Lodders et al. (2009) * ``allen``: Allen (1973) * ``ra``: Ross & Aller (1976) * ``grevesse``: Grevesse et al. (1992) * ``gs``: Grevesse & Sauval (1998) * ``lodders``: Lodders proto-Solar (2003) * ``solar``: Lodders Solar Photospheric (2003) * ``ag``: Anders & Grevesse (1989) * ``asplund``: Asplund et al. (2009) :: module subroutine spex_model_abundance(this,abun,ier) class(sapi), intent(inout) :: this character*(*), intent(in) :: abun integer, intent(out) :: ier end subroutine For example:: call spex%abundance('asplund',ier) Abundance show """""""""""""" To get the current abundance table, use the ``abundance_show`` procedure:: call spex%abundance_show(iabun,abun,ier) Where ``iabun`` is the output number of the abundance set, and ``abun`` is the output abundance reference:: module subroutine spex_model_abundance_show(this,iabun,abun,ier) class(sapi), intent(inout) :: this integer, intent(out) :: iabun character*256, intent(out) :: abun integer, intent(out) :: ier end subroutine The procedure returns the reference as a text string:: call spex%abundance_show(iabun,abun) write(*,*) abun >>> Lodders et al. (2009) .. _spexapi_aerror: Aerror ------ Calculate the uncertainties for several parameters of a model component due to the uncertainties in the atomic data:: call spex%aerror(isect,icomp,pname,ikl,pvalue,aerror,ier) The Fortran interface:: module subroutine spex_model_atomic_error(this,isect,icomp,pname,ikl,pvalue,aerror,ier) class(sapi), intent(inout) :: this integer, intent(in) :: isect !! Sector number integer, intent(in) :: icomp !! Component number character*(*), intent(inout) :: pname !! Parameter name integer, intent(in) :: ikl !! Shell number (0: full band, 1: L-shell, 2: K-shell) real(dp), intent(out) :: pvalue !! Parameter value real(dp), intent(out) :: aerror !! Atomic error integer, intent(inout) :: ier end subroutine Example:: call spex%aerror(1,1,'08',0,pvalue,aerror) write(*,*) pvalue, aerror >>> 1.00 0.0678 .. _spexapi_calc: Calculate --------- Once the model sectors and components are set-up and the parameters are set, the model spectrum can be calculated using the SPEX ``calculate`` command. In the Fortran interface, we distinguish two different calculate commands. One command only recalculates the model (``calc_model``) and the other (``calc``) calculates the model and folds it with the response matrix:: call spex%calc_model(ier) :: module subroutine spex_model_calc(this,ier) class(sapi), intent(inout) :: this integer, intent(out) :: ier !! Error status end subroutine The general ``calc`` command looks like this:: call spex%calc() The general calculate command is actually a member of the fit library:: module subroutine spex_fit_eval(this) class(sapi), intent(inout) :: this end subroutine Example:: call spex%calc_model(ier) call spex%calc() .. _spexapi_com: Component --------- Spectral components, like power laws, thermal and absorption models are loaded using the SPEX ``comp`` command. The Fortran procedure is also ``comp``:: call spex%comp(name, is1, is2, ier) The requires the ``name`` of the spectral component and the range of sectors it needs to apply to. This is slightly different from the command-line version of SPEX. The Fortran interface looks like this:: module subroutine spex_model_comp(this, name, is1, is2, ier) class(sapi), intent(inout) :: this character*(*), intent(in) :: name !! input name of the component integer, intent(in) :: is1 !! sectors [isect(1):isect(2)] integer, intent(in) :: is2 integer, intent(out) :: ier !! status error end subroutine For example:: call spex%comp('cie',1,1,ier) See :ref:`chap:specmod` for a list of spectral components. Component delete """""""""""""""" Deleting a component from the model is done using the sector and component number of the component:: call spex%comp_del(is1, is2, ic1, ic2, ier) The command accepts a range of sectors and/or components to delete. ``is1`` and ``is2`` are the low and high values of the sector range to consider. ``ic1`` and ``ic2`` are the low and high values of the components to delete. This is the Fortran interface:: module subroutine spex_model_comp_del(this, is1, is2, ic1, ic2, ier) !! Deletes the components with number from range #i2: for sector range (optional) #i1. class(sapi), intent(inout) :: this integer, intent(inout) :: is1, is2 integer, intent(inout) :: ic1, ic2 integer, intent(out) :: ier end subroutine For example:: call spex%comp_del(1,1,2,2,ier) The command above deletes the second component in sector number 1. Component relate """""""""""""""" The relation between the additive and multiplicative components is set with a ``com rel`` command in SPEX. In the Fortran API this is:: call spex%comp_rel(is1, is2, ic1, ic2, irel, rel, ier) The relations can be set by sector and component range and the related multiplicative models should be entered (in the right order). The Fortran interface:: module subroutine spex_model_comp_rel(this, is1, is2, ic1, ic2, irel, rel, ier) class(sapi), intent(inout) :: this integer, intent(in) :: is1 integer, intent(in) :: is2 integer, intent(in) :: ic1 integer, intent(in) :: ic2 integer, intent(in) :: irel integer, intent(in),dimension(irel) :: rel integer, intent(out) :: ier end subroutine For example:: call spex%comp('reds',1,1,ier) call spex%comp('hot',1,1,ier) call spex%comp('cie',1,1,ier) rel = (\1,2\) call spex%comp_rel(1,1,3,3,2,rel,ier) .. _spexapi_dist: Distance -------- To calculate fluxes and luminosities, SPEX needs an assumed distance of the source. In SPEX this is done with the ``distance`` command. The distance can be set with the ``distance`` procedure:: call spex%distance(is1,is2,dist,unit) where ``is1`` and ``is2`` are the sector number range, ``dist`` the distance and ``unit`` the unit of the distance that is put in. The Fortran interface:: module subroutine spex_model_dist(this, is1, is2, dist, uword, ier) class(sapi), intent(inout) :: this integer, intent(in) :: is1 !! First of sector range integer, intent(in) :: is2 !! Last of sector range real(dp), intent(in) :: dist !! Value character(len=8), intent(inout) :: uword integer, intent(out) :: ier end subroutine Examples:: If you do not want to set the distance, but just get the current parameters, the ``dist_get`` procedure can be used:: call spex%dist_get(isect, dis, ier) This procedure returns the ``dis`` object which contains the distances in all available units:: real(dp) :: h0 = 0.70_dp !! The Hubble constant in units of 100 km/s/Mpc real(dp) :: om = 0.30_dp !! Omega_matter real(dp) :: ov = 0.70_dp !! Omega_Lambda real(dp) :: or = 0.00_dp !! Omega_radiation real(dp) :: distance !! Distance in SPEX units 1E22 m real(dp) :: dm !! Distance in meter real(dp) :: dau !! Distance in A.U. real(dp) :: dly !! Distance in lightyear real(dp) :: dpc !! Distance in parsec real(dp) :: dkpc !! Distance in kiloparsec real(dp) :: dmpc !! Distance in megaparsec real(dp) :: dz !! Distance in redshift real(dp) :: dcz !! Distance in cz real(dp) :: age !! Lookback time in Gyr real(dp) :: dltt !! Light travel time distance (Mpc) real(dp) :: dl !! Luminosity distance (Mpc) real(dp) :: da !! Angular size distance One can write the desired distance to the terminal by:: call spex%dist_get(1,dis,ier) write(*,*) dis%dm ! Write the distance in meter for sector 1 Cosmology """"""""" Next to the distance, the cosmology used by SPEX can also be specified:: call spex%dist_cosmo(cospar,value,ier) The command can be used to set the values for the Hubble constant ``h0`` (70 km/s/Mpc), Omega Matter ``omega_m`` (0.3), Omega Lambda ``omega_l`` (0.7) and Omega R ``omega_r`` (0.0). The ``cospar`` variable contains the name of the parameter like a text string and the ``value`` variable contains the value for that parameter. This is the Fortran interface:: module subroutine spex_model_dist_cosmo(this, cospar, value, ier) class(sapi), intent(inout) :: this character*(*), intent(in) :: cospar !!Cosmological parameter real(dp), intent(in) :: value !!Value of the cosmological parameter integer, intent(inout) :: ier !!error status (0 is okay) end subroutine For example:: call spex%dist_cosmo('h0',75.0,ier) .. _spexapi_egrid: Energy grid ----------- The model energy grid can be manipulated with the SPEX ``egrid`` command. In Fortran, this command has been splitted into two varieties:: call spex%egrid(iopt, elow, ehigh, nbin, unit, ier) call spex%egrid_step(iopt, elow, ehigh, step, unit, ier) For the first method, ``egrid``, the number of spectral bins ``nbin`` is known, while for ``egrid_step`` the step size (``step``) is an input value. The lowest and highest energy of the grid needs to be provided using the ``elow`` and ``ehigh`` input values. The unit is a text string and the grid can be logarithmic if the ``log`` parameter is set to ``log``. The Fortran interface for egrid:: module subroutine spex_model_egrid(this, iopt, elow, ehigh, nbin, unit, ier) class(sapi), intent(inout) :: this character*(*), intent(in) :: iopt !! grid options: lin or log real(dp), intent(in) :: elow !! elow energy fbin=elow:ehigh real(dp), intent(in) :: ehigh !! ehigh energy fbin=elow:ehigh integer, optional, intent(inout) :: nbin !! nr of bins?? character*(*), optional, intent(inout) :: unit !! unit integer, intent(out) :: ier !! error status (0 is okay) end subroutine The Fortran interface for egrid_step:: module subroutine spex_model_egrid_step(this, iopt, elow, ehigh, step, unit, ier) class(sapi), intent(inout) :: this character*(*), intent(in) :: iopt !! grid options: lin or log real(dp), intent(in) :: elow !! elow energy fbin=elow:ehigh real(dp), intent(in) :: ehigh !! ehigh energy fbin=elow:ehigh real(dp), optional, intent(inout) :: step !! step stepa character*(*), optional, intent(inout) :: unit !! unit integer, intent(out) :: ier !! error status (0 is okay) end subroutine Examples:: call spex%egrid('log',0.1,10.0,9990,'kev',ier) call spex%egrid_step('lin',0.1,10.0,0.01,'kev',ier) Reading & saving grids """""""""""""""""""""" Grids can also be save and read from a text file. The two procedures below save and read a ``.egr`` file, respectively:: call spex%egrid_read(readfile,ier) call spex%egrid_write(savefile,ier) The ``savefile`` or ``readfile`` parameter should provide the method with the filename to save or read, including the ``.egr`` extension! If necessary, the full path to the file can be included. The Fortran interface:: module subroutine spex_model_egrid_write(this, filenam, ier) !! Write and save the calculated model energy grids class(sapi), intent(inout) :: this character*(*), intent(in) :: filenam !! output file integer, intent(out) :: ier !! error status (0 is okay) end subroutine module subroutine spex_model_egrid_read(this, filenam, ier) !! Read model energy grids class(sapi), intent(inout) :: this character*(*), intent(in) :: filenam !! input file integer, intent(out) :: ier !! error status end subroutine Examples:: call spex%egrid_write('mygrid.egr') call spex%egrid_read('mygrid.egr') Get & set custom grids """""""""""""""""""""" If the grid needs to be transferred from or to Fortran memory, then the ``get`` and ``ingrid`` methods can be used:: call spex%egrid_get(neg,eg,egb,deg,sener,wener,ier) call spex%egrid_ingrid() The Fortran interface for ingrid:: module subroutine spex_model_egrid_ingrid(this, ingrid, ning, ier) class(sapi), intent(inout) :: this real(dp), dimension(ning), intent(in) :: ingrid integer, intent(in) :: ning integer, intent(out) :: ier end subroutine The Fortran interface for get:: module subroutine spex_model_egrid_get(this,neg,eg,egb,deg,sener,wener,ier) class(sapi), intent(inout) :: this integer, intent(out) :: neg !! Number of model bins real(dp), allocatable, intent(out) :: eg(:) !! Bin centers (keV) real(dp), allocatable, intent(out) :: egb(:) !! Bin upper boundaries (keV) real(dp), allocatable, intent(out) :: deg(:) !! Bin width (keV) real(dp), allocatable, intent(out) :: sener(:) !! Spectrum ph/s/bin real(dp), allocatable, intent(out) :: wener(:) !! Weights integer, intent(out) :: ier end subroutine The ``get`` routine returns the fortran egrid arrays. The ``ingrid`` routine requires an array containing the energies of the bin boundaries. Note that the number of elements of this array would be of length n + 1, where n is the number of bins in the array. .. _spexapi_elim: Flux & Luminosity ----------------- For each component, the fluxes and luminosities are calculated using the set distance and energy boundaries. These energy limits for the flux and luminosity can be set using the ``elim`` procedure:: call spex%elim(elow, ehigh, unit, ier) where ``elow`` is the lower boundary of the flux and ``ehigh`` the higher boundary. The ``unit`` determines the units of the input values, for example 'kev' for keV. The Fortran interface is:: module subroutine spex_model_elim(this, r1, r2, unit, ier) !! Calculates the model flux in a given energy interval for the current spectral model class(sapi), intent(inout) :: this real, intent(in) :: r1 !! lower value of the energy range real, intent(in) :: r2 !! upper value of the energy range character*(*), intent(inout), optional :: unit !! given unit: keV, eV, Ryd, J, Hz, A, nm integer, intent(inout) :: ier !! Error status end subroutine Examples:: call spex%elim(13.6E-3,13.6,unit='kev',ier) Get flux """""""" The fluxes and luminosities calculated in SPEX can be extracted using the ``flux_get`` method:: call spex%get_flux(isect, icomp, eflow, efhigh, cname, & flux_photflux, flux_enerflux, flux_fotlum, flux_enelum, status) The Fortran interface is:: module subroutine spex_model_get_flux(this, isect, icomp, eflow, efhigh, cname, & flux_photflux, flux_enerflux, flux_fotlum, flux_enelum, status) !! Get the model flux in a given energy interval for the current spectral model class(sapi), intent(inout) :: this integer, intent(inout) :: isect !! Input sector integer, intent(inout) :: icomp !! Input component real(dp), intent(inout) :: eflow !! lower energy boundary real(dp), intent(inout) :: efhigh !! upper energy boundary character*8, intent(out) :: cname !! name component real(dp), intent(out) :: flux_photflux, flux_enerflux, flux_fotlum, flux_enelum !! output fluxes integer, intent(inout) :: status !! Error status end subroutine .. _spexapi_ibal: Ionisation balance ------------------ There are several ionisation balances available in SPEX. The Urdampilleta ionisation balance is the current default set. The ionisation balance can be set using the ``ibal`` method:: call spex%ibal(ref,ier) The ``ref`` is the short text string describing the paper reference for the ionisation balance: * ``ar92``: Arnaud & Raymond (1992) for Fe, Arnaud & Rothenflug (1985) for other elements. * ``ar85``: Arnaud & Rothenflug (1985). * ``oldbryans``: Old Bryans et al. data (NOT recommended). * ``bryans09``: Bryans et al. (2009). * ``u17``: Urdampilleta et al. (2017). The Fortran interface is (with cname for ref):: module subroutine spex_model_ibal(this,cname,ier) !! Set type of ionisation balance class(sapi), intent(inout) :: this character*(*), intent(inout) :: cname !! ionisation balance abbreviation integer, intent(inout) :: ier !! Error end subroutine Examples:: call spex%ibal('u17',ier) Show """" To show the current ionisation balance, the ``ibal_show`` procedure can be used:: call spex%ibal_show(ier) This method returns the reference of the ionisation balance as a string to the terminal. The Fortran interface looks like this:: module subroutine spex_model_ibal_show(this, ier) !! Show the type of ionisation balance class(sapi), intent(inout) :: this integer, intent(in) :: ier !!Error status end subroutine Example:: call spex%ibal_show(ier) >>> Urdampilleta et al. (2017) Get """ To get the current ionisation balance in your program, the ``ibal_get`` procedure can be used:: call spex%ibal_get(ier) This method returns the reference of the ionisation balance and the ionisation balance number. The Fortran interface looks like this:: module subroutine spex_model_ibal_get(this, ibal_ref, ib, ier) !! get type of ionisation balance class(sapi), intent(inout) :: this character(len=32), intent(out) :: ibal_ref !! name of the reference of ionisation balance integer, intent(out) :: ib !! matching the numeric label to ibal-ref integer, intent(inout) :: ier !! Error status end subroutine Example:: call spex%ibal_get(ibal_ref, ib, ier) .. _spexapi_ion: Ion selection ------------- In original SPEX models that use the SPEX atomic data, ions can be turned on or off, or can be calculated using the old SPEX version 2 or the new SPEX version 3. In addition, the maximum principle quantum number (nmax) and the maximum angular momentum (lmax) can be set. The functions have been created such that each function selects the ions either by atomic number (z), iso-electronic sequence (iso) or ion (ion):: call spex%ions_ignore_all(ier) call spex%ions_ignore_iso(iso,ier) call spex%ions_ignore_z(z,ier) call spex%ions_ignore_ion(z,ion,ier) call spex%ions_use_all(ier) call spex%ions_use_iso(iso,ier) call spex%ions_use_z(z,ier) call spex%ions_use_ion(z,ion,ier) call spex%ions_mute_all(ier) call spex%ions_mute_iso(iso,ier) call spex%ions_mute_z(z,ier) call spex%ions_mute_ion(z,ion,ier) call spex%ions_unmute_all(ier) call spex%ions_unmute_iso(iso,ier) call spex%ions_unmute_z(z,ier) call spex%ions_unmute_ion(z,ion,ier) call spex%ions_old_all(ier) call spex%ions_old_iso(iso,ier) call spex%ions_old_z(z,ier) call spex%ions_old_ion(z,ion,ier) call spex%ions_ql_all(ier) call spex%ions_ql_iso(iso,ier) call spex%ions_ql_z(z,ier) call spex%ions_ql_ion(z,ion,ier) call spex%ions_new_all(ier) call spex%ions_new_iso(iso,ier) call spex%ions_new_z(z,ier) call spex%ions_new_ion(z,ion,ier) Examples:: call spex%ions_ignore_ion(26,25,ier) ! Ignore Fe XXV call spex%ions_new_z(8,ier) ! Use new line database for Oxygen Show """" The ion selections can be shown in the terminal by calling the ``ions_show`` procedure below:: call spex%ions_show(ier) Line selection """""""""""""" Up to 10 specific lines can be 'muted' using the ``ions_line`` procedure below:: call spex%ions_line(mute,lid,z,ion,ier) The Fortran interface is:: module subroutine spex_model_ions_line(this, mute, lid, z, ion, ier) class(sapi), intent(inout) :: this logical, intent(in) :: mute !! Mute line .true. / Unmute .false. integer, intent(in) :: lid !! Line number to mute/unmute integer, intent(in) :: z !! Atomic number integer, intent(in) :: ion !! Ionisation stage integer, intent(inout) :: ier end subroutine Example:: call spex%ions_line(.true.,1,26,25,ier) In addition to the line mute procedure, there are a couple of convenience functions:: call spex%ions_line_show() ! Shows list of muted lines in terminal call spex%ions_line_unmute_all() ! Unmutes all lines (resets to normal) .. _spexapi_par: Setting parameters ------------------ Model parameters in SPEX are set using the ``par`` command. Since this command has subcommands, there are a number of methods to cover most of the functionality in Fortran. The most basic function is to set a parameter value:: call spex%par_set_value(isect,icomp,pname,val,ier) ! For numeric parameters call spex%par_set_avalue(isect,icomp,pname,avalue,ier) ! For text string parameters (like filenames) These are their Fortran interfaces:: module subroutine spex_model_par_set_value(this, isect, icomp, pname, val, ier) class(sapi), intent(inout) :: this integer, intent(in) :: isect !! Sector number of parameter integer, intent(in) :: icomp !! Component number of parameter character*(*), intent(in) :: pname !! Parameter name real, intent(in) :: val !! New parameter value integer, intent(out) :: ier !! error status end subroutine module subroutine spex_model_par_set_avalue(this, isect, icomp, pname, avalue, ier) class(sapi), intent(inout) :: this integer, intent(in) :: isect !! Sector number of parameter integer, intent(in) :: icomp !! Component number of parameter character*(*), intent(in) :: pname !! Parameter name character*(*), intent(in) :: avalue !! Parameter ascii value integer, intent(out) :: ier !! error status end subroutine The ``par_set_value`` method is used for setting numerical values. It needs the sector number (isect), component number (icomp) and the name of the parameter (name) to set. For text values, like filenames of model input files, the ``par_set_avalue`` method is used. The usage is very similar to the ``par_set_value`` method, but just with the difference a text string is passed instead of a value. Text parameters cannot be free parameters as well. Examples:: call spex%par_set_value(1,1,'norm',1E+8,ier) call spex%par_set_avalue(1,1,'file','dist.dat',ier) Fix & Free parameters """"""""""""""""""""" Many times, we want to fix and free parameters without changing the values. For this purpose, there is one procedure:: call spex%par_status(isect, icomp, pname, free, ier) Where ``isect`` is the sector number, ``icomp`` the component number and ``pname`` is the parameter name. If the ``free`` parameter is .true. the parameter is free, and frozen when .false. The Fortran interface looks like this:: module subroutine spex_model_par_status(this, isect, icomp, pname, free, ier) class(sapi), intent(inout) :: this integer, intent(in) :: isect !! Sector number of parameter integer, intent(in) :: icomp !! Component number of parameter character*(*), intent(in) :: pname !! Parameter name logical, intent(inout) :: free !! logical status integer, intent(out) :: ier !! error status end subroutine Examples:: call spex%par_status(1,1,'26',.true.,ier) call spex%par_status(1,1,'t',.false.,ier) Parameter range """"""""""""""" Parameters have ranges in which they can be safely varied without causing undesired errors or unphysical results. These ranges can be set using the ``par_set_range`` method:: call spex%par_set_range(isect, icomp, pname, low, upp, ier) In addition to the sector number (``isect``), component number (``icomp``), and the parameter name (``pname``), this function needs the lower (``low``) and upper range (``upp``) limits of the parameter. The Fortran interface looks like this:: module subroutine spex_model_par_set_range(this, isect, icomp, pname, low, upp, ier) class(sapi), intent(inout) :: this integer, intent(in) :: isect !! Sector number of parameter integer, intent(in) :: icomp !! Component number of parameter character*(*), intent(in) :: pname !! Parameter name real, intent(in) :: low !! Parameter lower value of range real, intent(in) :: upp !! Parameter upper value of range integer, intent(out) :: ier !! Error status end subroutine Example:: call spex%par_set_range(1,1,'t',1.0,10.0,ier) Couple parameters """"""""""""""""" Parameters can be coupled to each other such they have the same values in the fit. Or, optionally, remain coupled with a given multiplication factor. The Fortran procedure for this is ``par_couple``:: call spex%par_couple(isect, icomp, iname, csect, ccomp, cname, factor, ier) This is the Fortran interface:: module subroutine spex_model_par_couple(this, isect, icomp, iname, csect, ccomp, cname, factor, ier) class(sapi), intent(inout) :: this integer, intent(in) :: isect !! Sector number of parameter to link integer, intent(in) :: icomp !! Component number of parameter to link character*(*), intent(inout) :: iname !! Parameter name to link integer, intent(in), optional :: csect !! Sector number of target parameter integer, intent(in), optional :: ccomp !! Component number target of parameter character*(*), intent(inout) :: cname !! Parameter name of target real, intent(in) :: factor !! Coupling factor integer, intent(out) :: ier !! error status end subroutine The parameter located in ``isect``, ``icomp`` and with ``iname`` will be coupled to the parameter in ``csect``, ``ccomp``, and ``cname``. The ``factor`` sets the multiplication factor for the coupling. To decouple a parameter again, use:: call spex%par_decouple(isect, icomp, iname, ier) This is the Fortran interface:: module subroutine spex_model_par_decouple(this, isect, icomp, iname, ier) class(sapi), intent(inout) :: this integer, intent(in) :: isect !! Sector number of parameter integer, intent(in) :: icomp !! Component number of parameter character*(*), intent(inout) :: iname !! Parameter name integer, intent(out) :: ier end subroutine Examples:: call spex%par_couple(1, 2, 't', 1, 1, 't', 0.5, ier) ! Couple the temperature in component 2 to 0.5 times the temperature in component 1 call spex%par_decouple(1, 2, 't', ier) Show parameters """"""""""""""" Show the model parameters in the terminal. One can specify a couple of options to show more or less information:: call spex%par_show(free) Example:: call spex%par_show(free=.true.) Also individual components of the par show command can be shown:: call spex%par_show_flux() ! Shows the flux overview for the model call spex%par_show_couple() ! Shows the coupled parameters Get parameters """""""""""""" When doing an analysis it could be very helpful to get the value of a parameter:: call spex%par_get_value(in,is,ic,pval,free,low,upp,ier) This is the Fortran interface:: module subroutine spex_model_par_get_value(this,in,is,ic,pval,free,low,upp,ier) class(sapi), intent(inout) :: this character*(*), intent(inout) :: in !!parameter name integer, intent(in) :: is !!sector number integer, intent(in) :: ic !!component number real, intent(out) :: pval !!parameter value logical, intent(out) :: free !!true if parameter is free real, intent(out) :: low !!lower allowed limit real, intent(out) :: upp !!upper allowed limit integer, intent(out) :: ier !!error status end subroutine This function returns for parameter ``in``, sector number ``is`` and component number ``ic``, the parameter value ``pval``, the free status ``free``, and the lower and upper range ``low`` and ``upp``. Example:: call spex%par_get_value('t',1,1,pval,free,low,upp,ier) Write parameters to .com file """"""""""""""""""""""""""""" The current parameter settings can be saved to a command file (.com) and be loaded later by the ``log_exe`` command. The ``par_write`` method in Fortran is called like this:: call spex%par_write(filename, overwrite) The Fortran interface for this procedure looks like this:: module subroutine spex_model_par_write(this, filename, overwrite) class(sapi), intent(inout) :: this character*(*), intent(in) :: filename !name of the command file logical, intent(in) :: overwrite !overwrite flag end subroutine Example:: call spex%par_write('myparam.com', .true.) ! overwrites the file 'myparam.com' .. _spexapi_sector: Sectors ------- Sectors group spectral components to form the model for a particular source or phenomenon. If the sectors need a different response, the sectors should also be defined in the .spo and .res files. When starting SPEX, the number of sectors is 1 by default, even if loaded data files contain more sectors. Sectors can be added to SPEX with the ``sector`` command. In Fortran a new sector is created easily with the ``sector_new`` procedure:: call spex%sector_new(ier) This creates an empty sector. Sometimes, the new sector needs to have the same components as a previous one. In this case, the sector (with number ``isect``) can be copied:: call spex%sector_copy(isect,ier) If a sector is no longer needed, it can be deleted:: call spex%sector_del(sect1,sect2,ier) ! Delete sectors in the range from ``sect1`` to ``sect2``. Examples:: call spex%sector_new(ier) call spex%sector_copy(1,ier) call spex%sector_delete(1,1,ier) Since the sector contains the spectral model before convolving it with the response matrix, it can be helpful to get the model spectrum for, for example, the file model or get the spectrum in your program. There are two procedures for this:: call spex%sector_adump(isect, filenam, overwrite) call spex%sector_get_spectrum(isect, neg, eg, lum, ier) These are their Fortran interfaces:: module subroutine spex_model_sector_adump(this, isect, filenam, overwrite) class(sapi), intent(inout) :: this integer, intent(in) :: isect !! Sector number to dump to file character(len=128), intent(in) :: filenam !! Filename of output file logical, intent(in) :: overwrite !! Overwrite existing file (true/false) end subroutine module subroutine spex_model_sector_get_spectrum(this, isect, neg, eg, lum, ier) class(sapi), intent(inout) :: this integer, intent(in) :: isect integer, intent(out) :: neg !! Number of bins real(dp), allocatable, intent(out) :: eg(:) !! Energy grid real(dp), allocatable, intent(out) :: lum(:)!! Luminosity in 10^44 ph/s/keV integer, intent(out) :: ier end subroutine .. _spexapi_var: Plasma model parameters ----------------------- There are a number of settings for the SPEX plasma models that can be changed by the user. In SPEX these are done using the ``var`` command. The ``var`` commands have been implemented in Fortran through the methods below. Free-bound accuracy """"""""""""""""""" The free-bound accuracy (``fbacc``) can be set by:: call spex%var_gacc(fbacc, ier) call spex%var_gacc_reset(ier) Example:: call spex%var_gacc(1.E-7,ier) Line emission contributions """"""""""""""""""""""""""" The line processes can be switched off:: call spex%var_line(proc,stat,ier) The Fortran interface looks like this:: module subroutine spex_model_var_line(this, proc, stat, ier) class(sapi), intent(inout) :: this character*(*), intent(in) :: proc !! Process name logical, intent(in) :: stat !! Process on/off integer, intent(out) :: ier end subroutine Example:: call spex%var_line('ex',.false.,ier) Doppler broadening """""""""""""""""" The Doppler broadening can be set by:: call spex%var_doppler(dopp,ier) module subroutine spex_model_var_doppler(this, dopp, ier) class(sapi), intent(inout) :: this integer, intent(in) :: dopp !! Type of broadening included integer, intent(out) :: ier end subroutine Example:: call spex%var_doppler(1,ier) SPEXACT version 3 calculations """""""""""""""""""""""""""""" The use of SPEX version 3 atomic data can be set by:: call spex%var_calc(ivar,ier) Where ``ivar`` is either ``old``, ``new``, or ``qc``. Example:: call spex%var_calc('new',ier) Occupation numbers starting values """""""""""""""""""""""""""""""""" Set the occupation number starting values:: call spex%var_occstart(levdist,ier) Example:: call spex%var_occstart('ground',ier) SPEXACT version 2 settings (MEKAL) """""""""""""""""""""""""""""""""" Specific SPEX version 2 MEKAL settings can be changed by (TBD):: call spex%var_mekal() Examples:: call spex%var_mekal('fe17', .false.) Multi-Maxwellians for the ionisation balance """""""""""""""""""""""""""""""""""""""""""" call spex%var_ibalmax(maxw,ier) Example:: call spex%var_ibalmax(.false.,ier) SPEXACT version 3 cooling """"""""""""""""""""""""" Switch cooling methods on or off:: call spex%var_newcoolexc(cool, ier) Example:: call spex%var_newcoolexc(.false.,ier) And for the cooling by di-electronic recombination:: call spex%var_newcooldr(cool,ier) Example:: call spex%var_newcooldr(.false.,ier) Charge exchange recombination and ionization """""""""""""""""""""""""""""""""""""""""""" Set the origin of the charge exchange recombination and ionization rates:: call spex%var_cxcon(cxcon) Example:: call spex%var_cxcon(1) Set photo-ionisation cross-sections """"""""""""""""""""""""""""""""""" The photo-ionisation cross-sections can be set by:: call spex%var_pixsec(pixsec) Example:: call spex%var_pixsec(2)