This is a python wrapper for the XWIND model. This is an analytic model for calculating the line profiles of outflowing winds in AGN. Specifically, this is designed for slow(ish) BLR scale winds. It is originally designed with the Fe-K
Internally, the routines used to calculate the line profiles are written in fortran, due to significant perfomance benefits. This is done using the numpy f2py bindings. Beyond compiling the fortran code (see Installation and the included compile.sh script), the user does not need to worry about this, as everythin on the user end is handled by the PyXWIND_object class, with the relevant subclasses being xw_line and xw_conv (see below for more details).
- Python 3.10 or above (tested with Python v.3.12.4 and v.3.13.5)
numpy(tested on version 1.26.4 and 2.3.3)matplotlib(tested on version 3.9.1 and 3.10.6)astropy(tested on version 7.1.0)- fortran compilor/python binder:
▸ If python 11 or lower: Any fortran complior should do
▸ If python 12 and above:mesonis required. Can be found at: https://mesonbuild.com/
This requirement comes from changes innumpyf2pybindings with python12
Currently:
- Clone the repository
- From within the main directory run the compile script compile.sh
./compile.sh
Once the compile script is run, and PyXWIND is added to the pythonpath, it can be imported as:
import pyxwind
If you do not want to edit the pythonpath manually, you can also do:
import sys
sys.path.append('/path/to/PyXWIND')
import pyxwind
Within PyXWIND there are two main classes for the user to use: xw_line and xw_conv. The main difference between these is how the line profiles are calculated. In xw_line they are treated as additive components, whereas in xw_conv you need to supply an input spectrum which is then convolved with the xwind line shape. These are imported as:
from pyxwind import xw_line, xw_conv
For examples on how to use these see the scripts in the examples directory.
This is an overview of the parameters needed when initiating either xw_line or xw_conv. These are the same for both classes.
▸ M_BH: float, optional
Central black hole mass
NOTE: only plays a role if you need the physical density profile
For line profiles this does not matter, since those work in dimensionless units
Units:
Default: 1e8
▸ log_mdot_w: float, optional
Wind mass outflow rate, scaled by the Eddington mass accretion rate
Units: $\log{10} (\dot{M}_{w} / \dot{M}_{\rm{Edd}}) $
Default: -3
▸ r_in: float, optional
Inner wind launch radius
Units:
Defualt: 1000
▸ r_out: float
Outer launch radius
Units:
Default: 1500
▸ d_foci
Distance below the origi of the wind focus
Units:
Default: 1700
▸ fcov: float, optional
Wind covering fraction, as seen from the central source
Units:
Default: 0.5
▸ log_vinf: float, optional
Outflow velocity at infinity
Units:
Default: -3
▸ rv: float, optional
Velocity scale length (i.e. distance along streamline where
Units:
Default: 1000
▸ beta: float, optional
Velocity law exponent. Determines acceleration along streamline
Units: Dimensionless
Default: 1
▸ kappa: float, optional
Wind density gradient exponent. Determines launch efficiency with radius
Units: Dimensionless
Default: -1
▸ Afe: float, optional
Iron abundance, relative to solar
Units: [Fe/Fe_sol]
Default: 1
Below there is an overview of the key class methods. First giving the ones unique to xw_line and xw_conv, before finishing with the ones that exist in both classes.
▸ calc_xwindline(inc, E0, Ebins, vturb=0, edens_unit=True)
Calculates a sinlge line profile, assuming a delta function in the rest frame. Can be used for any rest frame energy
Parameters
-----------
▸ inc: float
Observer inclination
Units: degrees
▸ E0: float
Rest frame energy
Units: keV
▸ Ebins: ArrayLike
Energy bin edges (output will lave size len(Ebins)-1)
Units: keV
▸ vturb: float, optional
Turbulent velocity (assumed constant throughout wind)
Units: km/s
Default: 0
▸ edens_unit: bool, optional
If True convets output to phhotons/s/cm^2/keV
If False output is photons/s/cm^2/bin
Default: True
Returns
--------
▸ ph: ArrayLike
Output photon flux array
Shape: len(Ebins)-1
Units: set by edens_unit par
▸ calc_xwindfe(inc, N0, gamma, Ebins, vturb=0, edens_unit=True, give_EW=False)
xwindline profile specific to Fe-K
Normalisation calculated self-consistently from density profile and input spectrum
Uses 7-Lorentzian Holzer et al. (1997) profile for the rest frame emission
This gives both Fe-K
Parameters
------------
▸ inc: float
Observer inclination
Units: degrees
▸ N0: float
Normalisation of illuminating X-ray spectrum (i.e central source)
Units: photons/s/cm^2 at 1 keV
▸ gamma: float
Photon index of illuminating X-ray spectrum
Units: Dimensionless
▸ Ebins: ArrayLike
Energy bin edges
Units: keV
▸ vturb: float, optional
Turbulent velocity
Units: km/s
Default: 0
▸ edens_units: bool, optional
If True, output has units: photons/s/cm^2/keV
If False, output has units: photons/s/cm^2/bin
Default: True
▸ give_EW: bool, optional
If True, also returnes line equivalent width (in units keV)
If False, only returnes photon spectrum
Default: False
Returns
---------
▸ ph: ArrayLike
Output photon flux array
Size: len(Ebins)-1
Units: set by edens_units par
▸ EW: float
ONLY returned IF give_EW=True
Line equivalent width
Units: keV
▸ set_input_spectrum(ear, ph, eunit='keV', phunit='photon_keV', check_unit=True)
Defines the input spectrum to be convolved
Internally the code uses units of photons/s/cm^2/bin
For a given eunit and phunit, this method automatically handles unit conversions
Parameters
------------
▸ ear: ArrayLike
Energy bin edges
▸ ph: ArrayLike
Photon flux array
Must be in a form of flux density (see phunit)
Size: len(ear)-1
▸ eunit: str, optional
Sets the input units of ear
Options: {'keV', 'Hz', 'AA'}
Note, AA=Ångstrom
Default: keV
▸ phunit: str, optional
Sets the input unit of ph (note, must be a form of flux density)
Default: 'photon_keV'
Options: {'photon_keV', 'photon_Hz', 'photon_AA',
'cgs_keV', 'cgs_Hz', 'cgs_AA',
'SI_keV', 'SI_Hz', 'SI_AA'}
Note: photon=photons/s/cm^2
cgs=erg/s/cm^2
SI=W/m^2
Such that photon_keV=photon/s/cm^2/keV
▸ check_unit: bool, optional
If True, then checks the input unit and converts to internal units
NOTE: This should always be set to True unless you are specifically
dealing with things in units of photons/s/cm^2/bin
Returns
---------
▸ None
▸ do_convolve(inc, vturb=0, conv_unit=True)
Does the model convolution
Assumes set_input_spectrum() has been defined frist
Parameters
------------
▸ inc: float
Observer inclination
Units: degrees
▸ vturb: float, optional
Turbulent velocity
Units: km/s
Default: 0
▸ conv_unit: bool, optional
If True, converts output back to units given by user in set_input_spectrum()
If False, output is given in photons/s/cm^2/bin
Default: True
Returns
---------
▸ ph_conv: ArrayLike
Convolved spectrum
▸ calc_los_NH(inc)
Calculates column-density along a given line-of-sight
Parameters
------------
▸ inc: float
Line of sight inclination (measured from z-axis)
Units: degrees
Returns
---------
▸ Nh: float
Line of sight column-density
Units: cm^{-2}
▸ calc_NH_profile()
Calculates Nh profile of the wind as a function of theta (line-of-sight)
Uses internal grid in cos_theta
Returns
---------
▸ NHarr: ArrayLike
Array of line-of-sight column-densities
Units: cm^{-2}
▸ thetas: ArrayLike
Array of lines-of-sight (corresponding to NHarr)
Units: degrees
▸ plot_wind(profile_type, ax=None, cmap='jet', cnorm='log', cscale=None, inc_cbar=False, cbar_label='none', cbar_loc='right', show_axlabel=True, show=False)
Plots a 2D map (in x,z plane) of the wind geometry
The colour gradient, set by profile_type, corresponds to a physical wind property (i.e density, emissivity, etc)
Parameters
-------------
▸ profile_type: str
What wind parameter to plot, shown as the colour gradient
Options: {'ndens', 'vl', 'vphi', 'fluoresence', 'rel_emiss', 'vol_emiss'}
▸ ax: None|pyplot axis, optional
Pyplot axis toplot on
If None, then generates own figure+axis
Default: None
▸ cmap: str, optional
Colourmap to use (must correspond to a valid pyplot colourmap string)
Default: 'jet'
▸ cnorm: str, optional
Colourmap normalisation scale
Options: {'log', 'linear'}
Default: 'log'
▸ cscale: pyplot normalisation object, optional
User defined normalisation scale (overwrites cnorm)
Must correspond to a matplotlib.colors normalisation object
Default: None
▸ inc_cbar: bool, optional
If True, includes colourbar
Default: False
▸ cbar_label: str, optional
Label for the colourbar
If 'none' then automatically defined by the profile_type
Default: 'none'
▸ cbar_loc: str, optional
Where to place the colourbar
Options: {'bottom', 'top', 'left', 'right'}
Default: 'right'
▸ show_axlabel: bool, optional
If True, writes labels on x and z axis
Default: True
▸ show: bool, optional
If True, calls plt.show() to display plot
Default: False