-
Notifications
You must be signed in to change notification settings - Fork 3
Add flux spectra #15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Add flux spectra #15
Changes from 1 commit
4a7483e
57df560
1db5b83
f62f15e
ebf9d21
798edf1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,8 +12,56 @@ | |
|
||
__all__ = ['XSpectrum'] | ||
|
||
def calculate_flux_spectrum(spec, counts=None): | ||
""" | ||
Convert a spectrum from units of photon counts to | ||
units of photon flux. | ||
|
||
**Warning**: You should do this for plotting *only*. | ||
Converting from flux to counts, as is done in the detector, | ||
involves a convolution with the response matrix of the detector. | ||
Deconvolving this correctly is very hard, and not done in this | ||
function. This is for visualization purposes only! | ||
|
||
Parameters | ||
---------- | ||
spec : clarsach.XSpectrum object | ||
An XSpectrum object containing the X-ray spectrum | ||
|
||
counts : iterable | ||
An array with counts to be converted to the flux | ||
If this is None, use the `counts` attribute of the `spec` | ||
object. | ||
|
||
Returns | ||
------- | ||
flux_spectrum: | ||
The flux spectrum | ||
|
||
""" | ||
|
||
# make a flat spectrum so that I can integrate | ||
# ARF and RMF only | ||
flat_model = np.ones_like(spec.counts) * (spec.rmf.energ_hi - | ||
spec.rmf.energ_lo) | ||
|
||
# now apply ARF to the flat model | ||
m_arf = spec.arf.apply_arf(flat_model) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use
|
||
|
||
# apply RMF to the flat model | ||
m_rmf = spec.rmf.apply_rmf(m_arf) | ||
|
||
# divide the observed counts by the flat model with the ARF/RMF applied | ||
if counts is None: | ||
flux_spec = spec.counts / m_rmf / spec.exposure | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If |
||
else: | ||
flux_spec = counts / m_rmf / spec.exposure | ||
|
||
return flux_spec | ||
|
||
# Not a very smart reader, but it works for HETG | ||
class XSpectrum(object): | ||
|
||
def __init__(self, filename, telescope='HETG'): | ||
assert telescope in ALLOWED_TELESCOPES | ||
|
||
|
@@ -94,3 +142,5 @@ def _read_chandra(self, filename): | |
self.arf = ARF(self.arf_file) | ||
self.exposure = ff[1].header['EXPOSURE'] # seconds | ||
ff.close() | ||
|
||
self.flux = calculate_flux_spectrum(self, None) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is what I'm working on in xpysis.
I am certain that you should not multiply by (energ_hi - energ_lo). When I do this with the test data on Mrk 421, it gives me something that I know is an order of magnitude off from the true values
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To see how this method for unfolding data performs, see this notebook:
https://github.com/eblur/xpysis/blob/master/notebooks/Example1_fit_HETG_powerlaw.ipynb
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Regarding the multiplication by
(energ_hi - energ_lo)
: I don't know how to square that circle, because I have a case where the exact opposite is true: if I don't multiply by the bin width, I end up with something that is no longer a power law, because my power law and the fact that the energy bins are logarithmic messes up the slope.I don't know how to make sense of that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh my. Is it instrument dependent? What data set are you using where you do need to multiply by the bin width?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, right now simulated Chandra/HETG data, actually, so this is the same instrument.
Here's a test I just did: I took the simulated Chandra/HETG spectrum (the one that's just a power law), and applied both methods to it (once without multiplying by the energy bin, and once with), and then plotted that with a comparison to the code that the sherpa manual suggests using.
Here's the plot:

I can see that this is about an order of magnitude off from what sherpa calculates (and sherpa doesn't have those weird features), but the one where I don't multiply by the bin width is off, too, and it has a different slope. So, if sherpa is right, currently neither of our methods is working correctly. If sherpa is wrong, then I don't know at all anymore what's going on.
Victoria and I tested this by eye when I was at ESTEC: the code I used (which is similar to what I implemented in this PR) seemed to give the right answer (where "right" == "the same as ISIS").
I am super confused.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Those features (e.g. the bump around 2 keV) should definitely not be there. Sherpa is right in this case.
If the fitting is still working (i.e. giving us a power law with photon index = 2), then I'm inclined to say it's our method of unfolding the data. If the fitting is not working any more, then it's something wrong with the way we are applying the response.
Thank you for testing this, as I have never been able to install sherpa properly and can only use ISIS as a comparison.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
By the way, did you notice PR #16 ? If you have not yet reviewed this change, this could be the problem.
(but even after fixing it in my own code, I still get those weird features around 2 keV, which are clearly artifacts from the ARF)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, so I'm pretty sure it's the unfolding, not the application of the ARF/RMF, because I tested those on simulated spectra with a direct comparison to sherpa, and that gives me correct results for all instruments I tested so far.
Here's a slide I found in a etalk by David Huenemoerder that deals with this:

I find that incredibly confusing, though. The words sound like we should be integrating: if S(E) = 1, then we want the counts per unit flux, then we should be integrating S(E) in order to get something that's in the same units as the data. But the equation makes it look like we shouldn't be integrating. He does mention, though, that you can find spurious features. I've been trying to figure out how exactly sherpa computes this plot, but so far, I've not managed to track it down within the source code.
Do you think it would help if we talked this through per telecon rather that GitHub issues next week?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, let's make some time to skype about this. I think it's easier in person. Plus we may as well talk about some other considered changes. I am going home soon, so next week is good. I'll email you on Monday.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, I will go home soon, too, but first, two observations:
(1) The weird features in the spectrum are caused by applying
frac_expo
. I don't know why, but when I don't applyfrac_expo
, they go away.(2) It looks like there should definitely not be a
np.sum
in the expression for the RMF calculation. The reference implementation that I used to compare with some of the simulated data sets (NICER, HEXTE, Chandra etc) doesn't have a sum.If those two conditions are fulfilled, I get the same spectrum as sherpa does.