Chandra X-Ray Observatory
	(CXC)
Skip to the navigation links
Last modified: 30 Nov 2016

URL: http://cxc.harvard.edu/sherpa/threads/nustar_sim/

Simulating NuSTAR X-Ray Spectra with Sherpa

Sherpa Threads (CIAO 4.9 Sherpa v1)


Overview

Synopsis:

This thread illustrates the use of the Sherpa fake_pha command to simulate a hard X-ray emission spectrum of a supernova remnant which might be imaged by the detectors aboard the Nuclear Spectroscopic Telescopic Array (NuSTAR) satellite, launched in June 2012. NuSTAR, the first focusing high energy X-ray mission sensitive across the 5-80 keV range, is aimed at studying objects such as black holes, supernovae, and extremely active galaxies. Here, we use Sherpa to simulate a 1-D PHA spectrum using the currently available NuSTAR imaging ARF and RMF response files, in addition to a source model expression tailored to the Chandra X-ray spectrum of SN 1979C, suspected to harbor an accreting stellar-mass black hole.

Last Update: 30 Nov 2016 - updated for CIAO 4.9, fit results updated; no new content.


Contents


Quick Start to Simulating Data

All that is required to simulate a 1-D PHA NuSTAR data set in Sherpa is the following:

  • a source model expression defined with set_source
  • ARF & RMF instrument response files downloaded from the NuSTAR website
  • exposure time for the simulation in seconds

fake_pha will do the rest:


unix% ciao

ciao% sherpa

# Search available Sherpa models.

sherpa> list_models()

['atten',
 'bbody',
 'bbodyfreq',
 'beta1d',
 'beta2d',
  ...
 'xszvarabs',
 'xszvfeabs',
 'xszvphabs',
 'xszwabs',
 'xszwndabs',
 'xszxipcf']


#  Define a source model expression and assign it to an ID.

sherpa> set_source("faked", xswabs.gal*(xsmekal.tplasma+xsmekal.tplasma2+xspowerlaw.powlaw))


# Set model parameter values.

sherpa> set_par(gal.nH, 0.025, frozen=True)
sherpa> tplasma.redshift = 0.005  # frozen by default
sherpa> tplasma.kT = 1.1401      
sherpa> tplasma.norm = 3.86263e-06 
sherpa> tplasma2.redshift = 0.005  # frozen by default
sherpa> tplasma2.kT = 0.659763    
sherpa> tplasma2.norm = 2.62793e-05 
sherpa> powlaw.PhoIndex = 2.44436     
sherpa> powlaw.norm =  7.87378e-05


# Restrict energy range to which photons are sensitive to the
    optics and fake a PHA data set over the grid defined by the input response.

sherpa> fake_pha("faked", arf="point_30arcsecRad_1arcminOA.arf", rmf="nustar.rmf",
exposure=200000., backscal=1.0)


# Return information on the faked data set and associated responses.

sherpa> show_data("faked")

sherpa> calc_data_sum(id="faked")
sherpa> calc_energy_flux(id="faked")
sherpa> calc_photon_flux(id="faked") 


# Plot simulated data.

sherpa> plot_data("faked")


# Save simulated data.

sherpa> save_pha("faked", "nustar_sim_200ksec.pha")

This represents the quickest and simplest way to simulate a NuSTAR PHA data set in Sherpa. Simply start CIAO and Sherpa; define a source model expression in Sherpa and assign it to a data set ID such as "faked"; set model parameter values; and then run fake_pha according to your specifications. Read on to find a detailed explanation of each step of this quick-start recipe.


Simulating Data Step by Step:

Downloading Calibration Response Files

In order to simulate a NuSTAR X-ray spectrum, it is necessary to define an instrument response using the appropriate ARF and RMF files currently available for the mission. NuSTAR response files are available for download from the "For Researchers" page of the NuSTAR website (CalTech); the files used in this thread are:

  • point_30arcsecRad_1arcminOA.arfunweighted effective area for a 1' off-axis circular extraction region of radius 30''
  • nustar.rmfincludes detector efficiency
[Effective Area Comparison]
[Print media version: Effective Area Comparison]

Figure 1: Effective Area Comparison

Plot of the effective area of the combined NuSTAR detector units, compared to those of current X-ray observatories1 .

1http://www.nustar.caltech.edu/page/researchers


Establishing the Source Model Expression for the Simulation

We will use the Sherpa fake_pha command to simulate a NuSTAR PHA spectrum using a defined source model expression and instrument response as input. Details on the functionality of fake_pha, with other examples of its usage, are available in the ahelp file and the other Sherpa simulation threads.

The source model chosen for the simulation is defined with the Sherpa set_source command, as follows, where it is assigned to a string data set ID, "faked".

sherpa> set_source("faked", xswabs.gal*(xsmekal.tplasma+xsmekal.tplasma2+xspowerlaw.powlaw))

sherpa> set_par(gal.nH, 0.025, frozen=True)

sherpa> tplasma.redshift = 0.005  # frozen by default
sherpa> tplasma.kT = 1.1401      
sherpa> tplasma.norm = 3.86263e-06 

sherpa> tplasma2.redshift = 0.005  # frozen by default
sherpa> tplasma2.kT = 0.659763    
sherpa> tplasma2.norm = 2.62793e-05 

sherpa> powlaw.PhoIndex = 2.44436     
sherpa> powlaw.norm =  7.87378e-05 

Here we use a source model consisting of a combination of two thermal MEKAL components and a power-law, with parameter values chosen to give a good approximation the Chandra imaging spectra of SN 1979C in the 0.6-3 keV range (Patnaude et al., 2011). We can view the model parameter settings in this case using the print command, as the Sherpa show_source command only displays model information for models already assigned to data sets.

sherpa> print(gal)
xswabs.gal
   Param        Type          Value          Min          Max      Units
   -----        ----          -----          ---          ---      -----
   gal.nH       frozen        0.025            0       100000 10^22 atoms / cm^2

sherpa> print(tplasma)
xsmekal.tplasma
   Param        Type          Value          Min          Max      Units
   -----        ----          -----          ---          ---      -----
   t1.kT        thawed       1.1401       0.0808         79.9        keV
   t1.nH        frozen            1        1e-05        1e+19       cm-3
   t1.Abundanc  frozen            1            0         1000           
   t1.redshift  frozen        0.005            0           10           
   t1.switch    frozen            1            0            1           
   t1.norm      thawed  3.86263e-06            0        1e+24           

sherpa> print(tplasma2)
xsmekal.tplasma2
   Param        Type          Value          Min          Max      Units
   -----        ----          -----          ---          ---      -----
   t2.kT        thawed     0.659763       0.0808         79.9        keV
   t2.nH        frozen            1        1e-05        1e+19       cm-3
   t2.Abundanc  frozen            1            0         1000           
   t2.redshift  frozen        0.005            0           10           
   t2.switch    frozen            1            0            1           
   t2.norm      thawed  2.62793e-05            0        1e+24           

sherpa> print(powlaw)
xspowerlaw.powlaw
   Param        Type          Value          Min          Max      Units
   -----        ----          -----          ---          ---      -----
   p1.PhoIndex  thawed      2.44436           -2            9           
   p1.norm      thawed  7.87378e-05            0        1e+24     

Defining the Instrument Response for the Simulation

Note that the steps in this section are optional, as ARF and RMF (or RSP) filenames may be directly entered into the arf and rmf arguments of the fake_pha expression shown in the next section of this thread. However, if you would like to view the details of or modify the response used in the simulation, you should load the NuSTAR ARF and RMF responses into Sherpa as follows:

sherpa> nustar_arf=unpack_arf("point_30arcsecRad_1arcminOA.arf")

sherpa> nustar_rmf=unpack_rmf("nustar.rmf")

sherpa> print(nustar_arf)
name     = point_30arcsecRad_1arcminOA.arf
energ_lo = Float64[4096]
energ_hi = Float64[4096]
specresp = Float64[4096]
bin_lo   = None
bin_hi   = None
exposure = None

sherpa> print(nustar_rmf)
name     = nustar.rmf
detchans = 4096
energ_lo = Float64[4096]
energ_hi = Float64[4096]
n_grp    = UInt64[4096]
f_chan   = UInt32[1014481]
n_chan   = UInt32[1014481]
matrix   = Float64[5627679]
offset   = 0
e_min    = Float64[4096]
e_max    = Float64[4096]

The response data is loaded into variables nustar_arf and nustar_rmf with the unpack_arf and unpack_rmf commands. These variables will be used to assign the instrument response to the faked data set in the next section of this thread, "Running the Simulation with fake_pha."


Running the Simulation with fake_pha

Simulating the NuSTAR spectrum with Sherpa involves convolving the chosen source model expression with the corresponding NuSTAR response, and applying Poisson noise to the counts predicted by the model. All of these steps are performed by the fake_pha command, which has four required arguments: data set or model ID, ARF, RMF, and exposure time. We set the fake_pha arf and rmf arguments to the nustar_arf/nustar_rmf variables defined in the previous section, and the exposure argument to a value of 200 kiloseconds.

sherpa> fake_pha("faked", arf=nustar_arf, rmf=nustar_rmf, exposure=200000.)

This command associates the data/model ID "faked" with a simulated spectrum which is calculated over the grid defined by the NuSTAR instrument response, using the input exposure time and source model expression. Poisson noise is added to the modeled data.

We may use the show_data command to inspect the basic properties of the new data set; observe that the "name" field reads "faked", and the "exposure" field has been set to the chosen exposure time:

sherpa> show_data()
Data Set: faked
Filter: 1.6200-165.4200 Energy (keV)
Noticed Channels: 1-4096
name           = faked
channel        = Float64[4096]
counts         = Float64[4096]
staterror      = None
syserror       = None
bin_lo         = None
bin_hi         = None
grouping       = Float64[4096]
quality        = Float64[4096]
exposure       = 200000.0
backscal       = None
areascal       = None
grouped        = True
subtracted     = False
units          = energy
rate           = True
plot_fac       = 0
response_ids   = [1]
background_ids = []

RMF Data Set: faked:1
name     = nustar.rmf
detchans = 4096
energ_lo = Float64[4096]
energ_hi = Float64[4096]
n_grp    = UInt64[4096]
f_chan   = UInt32[1014481]
n_chan   = UInt32[1014481]
matrix   = Float64[5627679]
offset   = 0
e_min    = Float64[4096]
e_max    = Float64[4096]

ARF Data Set: faked:1
name     = point_30arcsecRad_1arcminOA.arf
energ_lo = Float64[4096]
energ_hi = Float64[4096]
specresp = Float64[4096]
bin_lo   = None
bin_hi   = None
exposure = None

The calc_data_sum and calc_energy_flux/calc_photon_flux commands may be used to return the total counts and integrated energy/photon flux of the faked data set over the entire energy range (as in this example), or within a specified 'lo' to 'hi' range:

sherpa> calc_data_sum(id="faked")
           235.0

sherpa> calc_energy_flux(id="faked")   # ergs/cm^2/sec/keV
           2.0588096229987197e-13         

sherpa> calc_photon_flux(id="faked")   # photons/cm^2/sec/keV
           2.9029199363519135e-05

The simulated data set may be visualized with the plot_data command, as shown below, and saved with print_window. Before plotting, we group the counts in the faked data spectrum such that each bin contains at least 1 count, and set both the X- and Y-axes of the plot to a logarithmic scale.

sherpa> group_counts("faked", 1)

sherpa> set_xlog()
sherpa> set_ylog()

sherpa> plot_data("faked")

sherpa> print_window("nustar_sim_data_200ksec.ps")

The resulting plot is shown Figure 2.

[Plot of simulated NuSTAR source spectra]
[Print media version: Plot of simulated NuSTAR source spectra]

Figure 2: Plot of simulated NuSTAR source spectrum

Plot of simulated hard X-ray NuSTAR imaging spectrum created with the Sherpa fake_pha command.

Note that had we not applied a customized, properly normalized source model expression to the faked data, we would have had to re-normalize the simulated data to match the known flux (or counts) of SN 1979C. This process is illustrated in the threads "Simulating Chandra ACIS-S Spectra with Sherpa" and "Simulating 1-D Data: the Sherpa fake_pha Command."


Writing the Simulated Data to Output Files

We may use the save_pha command to write the simulated data set to a PHA file, with a header containing the exposure time value and paths to the corresponding response files:


sherpa> save_pha("faked", "nustar_sim_200ksec.pha")

sherpa> !dmlist nustar_sim_200ksec.pha header | grep EXPOSURE
0002 EXPOSURE                 200000.0                    Real8     

sherpa> !dmlist nustar_sim_200ksec.pha header | grep ANCRFILE
0004 ANCRFILE             point_30arcsecRad_1arcminOA.arf String

sherpa> !dmlist nustar_sim_200ksec.pha header | grep RESPFILE
0006 RESPFILE             nustar.rmf                     String

Fitting the Simulated Data

A data set simulated with fake_pha may be fit as any other data set in Sherpa. For example, we can fit the simulated data with the same source model expression used to create it (and which is already assigned to it at this point), or define a different model. In this example, we choose to first fit the full range of the data using only the power-law model component already assigned to it (minus the thermal plasma models), and then fit again using the xskerrbb model, a multi-temperature blackbody model for a thin accretion disk around a Kerr black hole.

While the detectors onboard NuSTAR may be sensitive to 1.5-165 keV photons, the mirrors only focus ~5-80 keV photons, so we restrict the data used to an energy band in this range with the notice command. Before fitting, we check the energy range of the data set being considered in the analysis with the help of the the show_filter command:

sherpa> notice(5,80)
sherpa> show_filter()
Data Set Filter: faked
5.0400-102.1200 Energy (keV)

Since the data has been previously grouped, the filter uses the energies at the edges of the detector channels that contain the energies requested in the notice command.

Then, we change the fit statistic from the default χ2-Gehrels to C-Stat, the fit method from Lev-Mar to Nelder-Mead, and change the model assigned to data set "faked" from gal*(tplasma+tplasma2+powlaw) to just powlaw.

sherpa> set_source("faked", powlaw)

sherpa> set_method("neldermead")
sherpa> set_stat("cstat")
sherpa> fit("faked")
Dataset               = faked
Method                = neldermead
Statistic             = cstat
Initial fit statistic = 85.2051
Final fit statistic   = 85.0856 at function evaluation 279
Data points           = 98
Degrees of freedom    = 96
Probability [Q-value] = 0.779668
Reduced statistic     = 0.886308
Change in statistic   = 0.119471
   powlaw.PhoIndex   2.51675     
   powlaw.norm    9.11581e-05 

We can visualize the fit using the plot_fit command; first, we change the fit statistic back to χ2-Gehrels in order to calculate and view error bars overlaid on the data points in the plot.

sherpa> set_stat("chi2gehrels") 

sherpa> plot_fit("faked")

The resulting plot is shown in Figure 3.

Next, we change the source model for data set "faked" from powlaw to xskerrbb, set the fit statistic back to C-Stat, and re-fit the data with the prior knowledge that the source is ~5.2 Msun and ~15.2 Mpc away:

sherpa> set_source("faked", xskerrbb.b1)
sherpa> b1.Mbh = 5.2 # M_sun
sherpa> b1.Dbh.max = 1e5
sherpa> b1.Dbh = 15200 # in kpc
sherpa> freeze(b1.Mbh)
sherpa> freeze(b1.Dbh)
sherpa> thaw(b1.eta)
sherpa> thaw(b1.i)
sherpa> thaw(b1.hd)

sherpa> set_stat("cstat")

sherpa> fit("faked")
Dataset               = faked
Method                = neldermead
Statistic             = cstat
Initial fit statistic = 2731.28
Final fit statistic   = 85.8684 at function evaluation 2151
Data points           = 98
Degrees of freedom    = 92
Probability [Q-value] = 0.660206
Reduced statistic     = 0.933352
Change in statistic   = 2645.41
   b1.eta         0.70516     
   b1.a           0.577883    
   b1.i           55.9289     
   b1.Mdd         1.8086      
   b1.hd          4.35834     
   b1.norm        21.2022     

sherpa> thaw(b1.Mbh)
sherpa> thaw(b1.Dbh)
sherpa> fit("faked")
Dataset               = faked
Method                = neldermead
Statistic             = cstat
Initial fit statistic = 85.8684
Final fit statistic   = 85.8684 at function evaluation 650
Data points           = 98
Degrees of freedom    = 90
Probability [Q-value] = 0.60368
Reduced statistic     = 0.954094
Change in statistic   = 3.44863e-06
   b1.eta         0.705145    
   b1.a           0.577753    
   b1.i           55.9431     
   b1.Mbh         5.20052     
   b1.Mdd         1.80887     
   b1.Dbh         15200.2     
   b1.hd          4.35844     
   b1.norm        21.2056     

This time, we visualize the new fit using the Kerr black hole model with plot_fit_delchi, in order to also view the fit Δχ2 residuals.

sherpa> set_stat("chi2gehrels")

sherpa> plot_fit_delchi("faked")
sherpa> current_plot("plot2")
sherpa> lin_scale(Y_AXIS)

The residuals plot is shown in Figure 4.

[Plot of fit to simulated NuSTAR spectrum]
[Print media version: Plot of fit to simulated NuSTAR spectrum]

Figure 4: Plot of 'xskerrbb' model fit and Δχ2 residuals

Plot of Δχ2 residuals resulting from a fit to the simulated NuSTAR spectrum, using a multi-temperature blackbody model for a thin accretion disk around a Kerr black hole.

The plot may be saved to a PostScript (or other format) file with the print_window command:

sherpa> print_window("nustar_sim_fit_delchi_200ksec.ps")

Examining the Fit Results

We can explore the errors associated with the best-fit model parameters using the confidence command; the 68% confidence level values are returned by default (1σ), and may be changed with the set_conf_opt command. In this example, we run the confidence routine to check the errors on all of the thawed model parameters:

sherpa> set_conf_opt("fast", False)
sherpa> set_stat("cstat")

sherpa> conf("faked")
b1.eta lower bound:	-----
b1.i lower bound:	-33.6054
b1.eta upper bound:	1.1835
b1.a -: WARNING: The confidence level lies within (-1.003652e+00, -9.992149e-01)
b1.a lower bound:	-1.57919
b1.hd -: WARNING: The confidence level lies within (8.985514e-02, 9.432120e-02)
b1.hd lower bound:	-4.26635
b1.a upper bound:	-----
b1.i +: WARNING: The confidence level lies within (8.899949e+01, 8.900200e+01)
b1.i upper bound:	33.0576
b1.Mdd -: WARNING: The confidence level lies within (1.116911e-01, 1.163259e-01)
b1.Mdd lower bound:	-1.69487
b1.hd +: WARNING: The confidence level lies within (5.282249e+01, 5.282512e+01)
b1.hd upper bound:	48.4654
b1.Mdd +: WARNING: The confidence level lies within (2.162529e+01, 2.162780e+01)
b1.Mdd upper bound:	19.8177
b1.Mbh -: WARNING: The confidence level lies within (4.766085e-02, 4.764132e-02)
b1.Mbh lower bound:	-5.15287
b1.Mbh +: WARNING: The confidence level lies within (1.416745e+02, 1.416770e+02)
b1.Mbh upper bound:	136.475
b1.Dbh -: WARNING: The confidence level lies within (9.844005e-04, 4.922002e-04)
b1.Dbh lower bound:	-15200.2
b1.norm -: WARNING: The confidence level lies within (3.290231e-02, 3.280194e-02)
b1.norm lower bound:	-21.1728
b1.norm upper bound:	-----
b1.Dbh +: WARNING: The confidence level lies within (5.975455e+05, 5.975456e+05)
b1.Dbh upper bound:	582345
Dataset               = faked
Confidence Method     = confidence
Iterative Fit Method  = None
Fitting Method        = neldermead
Statistic             = cstat
confidence 1-sigma (68.2689%) bounds:
   Param            Best-Fit  Lower Bound  Upper Bound
   -----            --------  -----------  -----------
   b1.eta           0.705145        -----       1.1835
   b1.a             0.577753     -1.57919        -----
   b1.i              55.9431     -33.6054      33.0576
   b1.Mbh            5.20052     -5.15287      136.475
   b1.Mdd            1.80887     -1.69487      19.8177
   b1.Dbh            15200.2     -15200.2       582345
   b1.hd             4.35844     -4.26635      48.4654
   b1.norm           21.2056     -21.1728        -----

The set_conf_opt command issued before conf in the example above ensures that the currently set fit optimization method is used in the confidence calculation, instead of the (faster) Sherpa default Lev-Mar method.

The output of the confidence command shows that the hard upper and lower limits were hit for several parameters (denoted by the -----). This occurs when the parameter bound found by confidence lies outside the hard limit boundary for a model parameter, and could result from an issue with the signal-to-noise of the data, the applicability of the model to the data, systematic errors in the data, among other things.

The warning messages printed in the confidence output shown above occur where confidence cannot locate the minimum value of the fit statistic function, even though it is bracketed within an interval (perhaps due to poor resolution of the data or a discontinuity). In such cases, when the openinterval option of confidence is set to False (default), the confidence function will return the average of the open interval which brackets the minimum value.

The region-projection and interval-projection plotting commands are available to further explore the quality of a fit, through visualization of fitted model parameter value(s) as a function of fit statistic value.


Scripting It

The file fit.py is a Python script which performs the primary commands used above; it can be executed by typing exec(open("fit.py").read()) on the Sherpa command line.

The Sherpa script command may be used to save everything typed on the command line in a Sherpa session:

sherpa> script(filename="sherpa.log", clobber=False)

The CXC is committed to helping Sherpa users transition to new syntax as smoothly as possible. If you have existing Sherpa scripts or save files, submit them to us via the CXC Helpdesk and we will provide the CIAO/Sherpa 4.9 syntax to you.



History

21 Jan 2011 original version
15 Dec 2011 reviewed for CIAO 4.4: a work-around for a save_pha bug was added
04 Dec 2013 reviewed for CIAO 4.6: no changes
20 Feb 2015 updated for CIAO 4.7 and CY17 Chandra CfP utilizing the current NuSTAR proposal responses.
15 Dec 2015 updated for CIAO 4.8 and CY18 Chandra CfP utilizing the version 3 of the NuSTAR proposal responses.
30 Nov 2016 updated for CIAO 4.9, fit results updated; no new content.


Last modified: 30 Nov 2016
Smithsonian Institute Smithsonian Institute

The Chandra X-Ray Center (CXC) is operated for NASA by the Smithsonian Astrophysical Observatory. 60 Garden Street, Cambridge, MA 02138 USA.   Email:   cxchelp@head.cfa.harvard.edu Smithsonian Institution, Copyright © 1998-2017. All rights reserved.