SciPy

darkhistory.spec.spectrum.Spectrum

class darkhistory.spec.spectrum.Spectrum(eng, data, rs=-1.0, in_eng=-1.0, spec_type='dNdE')

Structure for particle spectra.

Parameters:
eng : ndarray

Abscissa for the spectrum.

data : ndarray

Spectrum stored as N or dN/dE.

rs : float, optional

The redshift (1+z) of the spectrum. Default is -1.

in_eng : float, optional

The injection energy of the primary, if this is a secondary spectrum. Default is -1.

mode : {‘N’, ‘dNdE’}, optional

Whether the input is N or dN/dE in each bin. Default is ‘dNdE’.

Attributes:
eng : ndarray

Abscissa for the spectrum.

dNdE : ndarray

dN/dE of the spectrum.

N : ndarray

N of the spectrum.

rs : float, optional

The redshift (1+z) of the spectrum. Set to -1 if not specified.

length : int

The length of the abscissa.

underflow : dict of str: float

The underflow total number of particles and total energy.

Methods

at_eng(new_eng[, left, right]) Interpolates the spectrum at a new abscissa.
contract(mat) Performs a dot product with the Spectrum.
engloss_rebin(in_eng, out_eng[, …]) Converts an energy loss spectrum to a secondary spectrum.
rebin(out_eng) Rebins according to a new abscissa.
rebin_fast(out_eng) Rebins the Spectrum with ‘N’ spec_type quickly.
redshift(new_rs) Redshifts the Spectrum object as a photon spectrum.
shift_eng(new_eng) Shifts the abscissa while conserving number.
switch_spec_type([target]) Switches between data being stored as N or dN/dE.
totN([bound_type, bound_arr]) Returns the total number of particles in part of the spectrum.
toteng([bound_type, bound_arr]) Returns the total energy of particles in part of the spectrum.
__init__(eng, data, rs=-1.0, in_eng=-1.0, spec_type='dNdE')

Initialize self. See help(type(self)) for accurate signature.

__add__(other)

Adds two Spectrum instances together, or an array to the spectrum. The Spectrum object is on the left.

The returned Spectrum will have its underflow reset to zero if other is not a Spectrum object.

Parameters:
other : Spectrum or ndarray

The object to add to the current Spectrum object.

Returns:
Spectrum

New Spectrum instance which has the summed spectrum.

Notes

This special function, together with Spectrum.__radd__(), allows the use of the symbol + to add Spectrum objects together.

__init__(eng, data, rs=-1.0, in_eng=-1.0, spec_type='dNdE')

Initialize self. See help(type(self)) for accurate signature.

__mul__(other)

Takes the product of the spectrum with a Spectrum object, array or number.

The Spectrum object is on the left.

Parameters:
other : Spectrum, ndarray, float or int

The object to multiply to the current Spectrum object.

Returns:
Spectrum

New Spectrum instance which has the multiplied spectrum.

Notes

This special function, together with Spectrum.__rmul__(), allows the use of the symbol * to multiply Spectrum objects or an array and Spectrum.

The returned Spectrum object has underflow set to zero if other is not a Spectrum object.

__neg__()

Negates the spectrum.

Returns:
Spectrum

New Spectrum instance with the spectrum negated.

Notes

The returned Spectrum object has underflow set to zero.

__radd__(other)

Adds two Spectrum instances together, or an array to the spectrum. The Spectrum object is on the right.

The returned Spectrum will have its underflow reset to zero if other is not a Spectrum object.

Parameters:
other : Spectrum or ndarray

The object to add to the current Spectrum object.

Returns:
Spectrum

New Spectrum instance which has the summed spectrum.

Notes

This special function, together with Spectrum.__add__(), allows the use of the symbol + to add Spectrum objects together.

__rmul__(other)

Takes the product of the spectrum with an array or number.

The Spectrum object is on the right.

Parameters:
other : ndarray, float or int

The object to multiply with the current Spectrum object.

Returns
——-
Spectrum

New Spectrum instance which has the multiplied spectrum.

Notes

This special function, together with Spectrum.__mul__(), allows the use of the symbol * to multiply Spectrum objects or an array and Spectrum.

The returned Spectrum object has its underflow set to zero.

__rsub__(other)

Subtracts this Spectrum from another or an array.

Parameters:
other : Spectrum or ndarray

The object from which to subtract the current Spectrum object.

Returns:
Spectrum

New Spectrum instance which has the subtracted spectrum.

Notes

This special function, together with Spectrum.__sub__(), allows the use of the symbol - to subtract or subtract from Spectrum objects.

__rtruediv__(other)

Divides a number or array by the spectrum.

The Spectrum object is on the right.

Parameters:
other : ndarray, float or int

The object by which to divide the current Spectrum object.

Returns
——-
Spectrum

New Spectrum instance which has the divided spectrum.

Notes

This special function, together with Spectrum.__truediv__(), allows the use of the symbol / to multiply Spectrum objects or an array and Spectrum.

The returned Spectrum object underflow is set to zero.

__sub__(other)

Subtracts a Spectrum or an array from this Spectrum.

Parameters:
other : Spectrum or ndarray

The object to subtract from the current Spectrum object.

Returns:
Spectrum

New Spectrum instance which has the subtracted spectrum.

Notes

This special function, together with Spectrum.__rsub__(), allows the use of the symbol - to subtract or subtract from Spectrum objects.

The returned Spectrum object underflow is reset to zero if other is not a Spectrum object.

__truediv__(other)

Divides the spectrum by an array or number.

The Spectrum object is on the left.

Parameters:
other : ndarray, float or int

The object to divide the current Spectrum object by.

Returns:
Spectrum

New Spectrum instance which has the divided spectrum.

Notes

This special function, together with Spectrum.__rtruediv__(), allows the use of the symbol / to multiply Spectrum objects or an array and Spectrum.

The returned Spectrum object underflow is set to zero.

__weakref__

list of weak references to the object (if defined)

at_eng(new_eng, left=-200, right=-200)

Interpolates the spectrum at a new abscissa.

Interpolation is logarithmic.

Parameters:
new_eng : ndarray

The new energies to interpolate at.

left : float, optional

Returns the value if beyond the first bin on the left. Default is to return -200, so that the exponential is small.

right : float, optional

Returns the value if beyond the last bin on the right. Default is to return -200, so that the exponential is small.

contract(mat)

Performs a dot product with the Spectrum.

Parameters:
mat : ndarray

The array to take the dot product with.

Returns:
float

The resulting dot product.

engloss_rebin(in_eng, out_eng, out_spec_type=None, fast=False)

Converts an energy loss spectrum to a secondary spectrum.

An “energy loss spectrum” is a distribution of outgoing particles as a function of energy lost \(\Delta\) saved in self.eng after some interaction for an incoming particle \(E'\) specified by in_eng. The “secondary spectrum” is simply the distribution of outgoing particles as a function of their own energy \(E\) instead, with abscissa out_eng.

Parameters:
in_eng : float

The injection energy of the primary which gives rise to self.dNdE as the energy loss spectrum.

out_eng : ndarray

The final energy abscissa to bin into. If not specified, it is assumed to be the same as the initial abscissa.

out_spec_type: {‘N’, ‘dNdE’}, optional

The spec_type of the output spectrum. If not specified, the output spectrum will have the same spec_type.

fast: bool, optional

If fast, uses Spectrum.rebin_fast() instead of Spectrum.rebin() for speed.

Notes

This function is simply a numerical version of the fact that

\[\frac{dN}{d \Delta}(\Delta) = \frac{dN}{dE} (E = E' - \Delta) \]

in discretized form, preserving the total number and total energy in the spectrum using Spectrum.rebin().

rebin(out_eng)

Rebins according to a new abscissa.

The total number and total energy is conserved.

If a bin in the old abscissa self.eng is below the lowest bin of the new abscissa out_eng, then the total number and energy not assigned to the lowest bin are assigned to the underflow.

If a bin in self.eng is above the highest bin in out_eng, a warning is thrown, the values are simply discarded, and the total number and energy can no longer be conserved.

Parameters:
out_eng : ndarray

The new abscissa to bin into.

Returns:
None

Notes

Total number and energy are conserved by assigning the number of particles \(N\) in a bin of energy \(E\) to two adjacent bins in the new abscissa out_eng, with energies \(E_\text{low}\) and \(E_\text{upp}\) such that \(E_\text{low} < E < E_\text{upp}\). The number of particles \(N_\text{low}\) and \(N_\text{upp}\) assigned to these two bins are given by

\[\begin{split}N_\text{low} &= \frac{E_\text{upp} - E}{E_\text{upp} - E_\text{low}} N \,, \\ N_\text{upp} &= \frac{E - E_\text{low}}{E_\text{upp} - E_\text{low}} N\end{split}\]

Rebinning works best when going from a finer binning to a coarser binning. Going the other way can result in spiky features, since the coarser binning simply does not contain enough information to reconstruct the finer binning in this way.

rebin_fast(out_eng)

Rebins the Spectrum with ‘N’ spec_type quickly.

Rebinning conserves total number and total energy. No checks are made: use with caution!

Parameters:
out_eng_interp : ndarray

The new abscissa to bin into. If self.eng has values that are smaller than out_eng[0] or larger than out_eng[-1], then the value is discarded without error.

See also

Spectrum.rebin()

Notes

This implementation is identical to Spectrum.rebin(), but works only if the spec_type is of type ‘N’, and further dispenses with underflow and other checks.

redshift(new_rs)

Redshifts the Spectrum object as a photon spectrum.

Parameters:
new_rs : float

The new redshift (1+z) to redshift to.

Examples

>>> eng = np.array([1, 10, 100, 1000])
>>> spec = Spectrum(eng, np.ones(4), rs=100, spec_type='N')
>>> spec.redshift(10)
>>> print(spec.N)
[1. 1. 1. 0.]
>>> print(spec.underflow['N'])
1.0
shift_eng(new_eng)

Shifts the abscissa while conserving number.

This function can be used to subtract or add some amount of energy from each bin in the spectrum. The dN/dE is adjusted to conserve number in each bin.

Parameters:
new_eng : ndarray

The new energy abscissa.

Returns:
None
switch_spec_type(target=None)

Switches between data being stored as N or dN/dE.

Parameters:
target : {‘N’, ‘dNdE’}, optional

The target type to switch to. If not specified, performs a switch regardless.

Notes

Although both N and dN/dE can be accessed regardless of which values are stored, performing a switch before repeated computations can speed up the computation.

totN(bound_type=None, bound_arr=None)

Returns the total number of particles in part of the spectrum.

The part of the spectrum can be specified in two ways, and is specified by bound_type. Multiple totals can be obtained through bound_arr.

Parameters:
bound_type : {‘bin’, ‘eng’, None}

The type of bounds to use. Bound values do not have to be within [0:length] for ‘bin’ or within the abscissa for ‘eng’. None should only be used when computing the total particle number in the spectrum.

Specifying bound_type='bin' without bound_arr returns self.N.

bound_arr : ndarray of length N, optional

An array of boundaries (bin or energy), between which the total number of particles will be computed. If bound_arr is None, but bound_type is specified, the total number of particles in each bin is computed. If both bound_type and bound_arr are None, then the total number of particles in the spectrum is computed.

For ‘bin’, bounds are specified as the bin boundary, with 0 being the left most boundary, 1 the right-hand of the first bin and so on. This is equivalent to integrating over a histogram. For ‘eng’, bounds are specified by energy values.

These boundaries need not be integer values for ‘bin’: specifying np.array([0.5, 1.5]) for example will include half of the first bin and half of the second.

Returns:
ndarray of length N-1, or float

Total number of particles in the spectrum, or between the specified boundaries.

Examples

>>> eng = np.array([1, 10, 100, 1000])
>>> N   = np.array([1, 2, 3, 4])
>>> spec = Spectrum(eng, N, spec_type='N')
>>> spec.totN()
10.0
>>> spec.totN('bin', np.array([1, 3]))
array([5.])
>>> spec.totN('eng', np.array([10, 1e4]))
array([8.])
toteng(bound_type=None, bound_arr=None)

Returns the total energy of particles in part of the spectrum.

The part of the spectrum can be specified in two ways, and is specified by bound_type. Multiple totals can be obtained through bound_arr.

Parameters:
bound_type : {‘bin’, ‘eng’, None}

The type of bounds to use. Bound values do not have to be within the [0:length] for ‘bin’ or within the abscissa for ‘eng’. None should only be used to obtain the total energy.

Specifying bound_type='bin' without bound_arr gives the total energy in each bin.

bound_arr : ndarray of length N, optional

An array of boundaries (bin or energy), between which the total number of particles will be computed. If unspecified, the total number of particles in the whole spectrum is computed.

For ‘bin’, bounds are specified as the bin boundary, with 0 being the left most boundary, 1 the right-hand of the first bin and so on. This is equivalent to integrating over a histogram. For ‘eng’, bounds are specified by energy values.

These boundaries need not be integer values for ‘bin’: specifying np.array([0.5, 1.5]) for example will include half of the first bin and half of the second.

Returns:
ndarray of length N-1, or float

Total energy in the spectrum or between the specified boundaries.

See also

Spectrum.totN()

Examples

>>> eng = np.array([1, 10, 100, 1000])
>>> N   = np.array([1, 2, 3, 4])
>>> spec = Spectrum(eng, N, spec_type='N')
>>> spec.toteng()
4321.0
>>> spec.toteng('bin', np.array([1, 3]))
array([320.])
>>> spec.toteng('eng', np.array([10, 1e4]))
array([4310.])

Previous topic

darkhistory.spec.spectrum

Next topic

darkhistory.spec.transferfunclist

This Page