irfpy.util.fluxtools
¶
Tools for flux (differential, velocity distribution)
Code author: Yoshifumi Futaana
This module provide tools for flux manipulations (differential flux, count rate, velocity distribution function)
Containers of differential flux and count rate in a spherical coordinates are
implemented in irfpy.util.energyspectrum
.
The velocity distribution functions are implemented
in irfpy.util.vdf
module.
Representation of the differential flux on grids in polar coordinates. |
|
|
Represent the count rate (counts per sec) on grids in polar frame. |
|
Represents the velocity distribution function on grids in polar frame |
|
Conversion from velocity distribution function to differential flux. |
|
Conversion from differential flux to velocity distribution function. |
|
Conversion from count rate to differential flux using g-factor. |
Code author: Yoshifumi Futaana
- irfpy.util.fluxtools.vdf2dflux(vdfun)[source]¶
Conversion from velocity distribution function to differential flux.
- Parameters:
vdfun (
irfpy.util.vdf.VelocityDistributionGrid
) – Velocity distribution function on polar grid.- Returns:
Differential flux object.
- Return type:
In MKSA, the conversion from VDF to Dflx is
\[J = \frac{2 f E}{m^2}\]Limitation: So far, the energy/theta/phi_grid_size is limited to default (see
irfpy.util.energyspectrum.DifferentialFluxGrid
. Only the central value is used for conversion.>>> vgrid = np.linspace(0.01, 1000e3, 96) # 96 velocity space >>> tgrid = np.linspace(30, 150, 32) # 32 polar steps >>> pgrid = np.linspace(-180, 180, 65)[:-1] # 64 azimuth steps >>> maxwell = vdf.maxwellVelocityDistributionGrid(1e6, [-400e3, 0, 0], 80e3, vgrid, np.deg2rad(tgrid), np.deg2rad(pgrid)) >>> maxwell_dflx = vdf2dflux(maxwell) >>> print('%.4f' % maxwell_dflx.density()) 0.9999 >>> v = maxwell_dflx.velocity_vector() >>> print('%.2f %.2f %.2f' % (v[0], v[1], v[2])) -400.02 -0.00 0.00
- irfpy.util.fluxtools.dflux2vdf(dflx)[source]¶
Conversion from differential flux to velocity distribution function.
- Parameters:
dflx – Differential flux object in
irfpy.util.energyspectrum.DifferentialFluxGrid
object.- Returns:
Velocity distribution function in
irfpy.util.vdf.VelocityDistributionGrid
class.
>>> vgrid = np.linspace(0.01, 1000e3, 96) # 96 velocity space >>> tgrid = np.linspace(30, 150, 32) # 32 polar steps >>> pgrid = np.linspace(-180, 180, 65)[:-1] # 64 azimuth steps >>> maxwell = vdf.maxwellVelocityDistributionGrid(1e6, [-400e3, 0, 0], 80e3, vgrid, np.deg2rad(tgrid), np.deg2rad(pgrid)) >>> maxwell_dflx = vdf2dflux(maxwell) >>> maxwell_vdf = dflux2vdf(maxwell_dflx) # Back again. >>> print('%.5f' % ((maxwell.data - maxwell_vdf.data) ** 2).max()) 0.00000
- irfpy.util.fluxtools.cnt2dflx_simple_convfact(count_rate, gfactor)[source]¶
Conversion from count rate to differential flux using g-factor.
Conversion from count rate to differential flux using g-factor (table) is implemented.
\[J = \frac{C}{G \times E}\]where C is the count rate [/s], G is the geometric factor including efficiency [cm2 sr eV/eV], and E is the energy [eV]. The obtained differential flux is J, with the unit of [/cm2 sr eV s].
The usage is identical to
dflx2cnt_simple_convfact()
, which provides inverse function.- Parameters:
count_rate (
irfpy.util.energyspectrum.CountRateGrid
) – Calculated count rate.gfactor – Geometric factor, in the same shape as
count_rate.data
(iene, ipol, iaz), or broadcast-able. If gfactor depends on the energy, and gfactor has the shape of (iene), which is not broadcastable. In such case, you may need to make the gfactor array by usingirfpy.util.nptools.broadcast_r()
. See the sample below.
- Returns:
Differential flux object.
- Return type:
- irfpy.util.fluxtools.dflx2cnt_simple_convfact(diff_flux, gfactor)[source]¶
Differential flux is converted to count rate.
With a simple conversion of “by definition”.
\[C = J \times G \times E\]where J is the differential flux [/cm2 s sr eV], G is the geometric factor including efficiency [cm2 sr eV/eV], E is the energy [eV] (not energy range). The returned count rate will be [/s].
- Parameters:
diff_flux (
irfpy.util.energyspectrum.DifferentialFluxGrid
) – Differential flux object.gfactor – Geometric factor, in the same shape as
dflx.data
(iene, ipol, iaz), or broadcast-able. If gfactor depends on the energy, and gfactor has the shape of (iene), which is not broadcastable. In such case, you may need to make the gfactor array by usingirfpy.util.nptools.broadcast_r()
. See the sample below.
- Returns:
Calculated count rate.
- Return type:
For comprehensive example, I first prepare the energy array for a “virtual” sensor:
>>> elist = [10, 20, 40, 80, 160, 320, 640, 1280, 2560, 5120] # 10 energy steps
Then, angle information of the sensor are defined.
>>> tlist = np.radians([15, 45, 75, 105, 135, 165]) # Polar angle, 6 channel >>> plist = np.radians([0, 45, 90, 135, 180, 225, 270, 315]) # Azimuth, 8 channels
As an exercise, I prepare the Maxwell distribution
>>> n = 1e6 # 1 /cc >>> vb = [200e3, 200e3, 0] # 200 km/s vx and vy >>> vth = 70e3 # 70 km/s thermal velocity >>> diff_flux = energyspectrum.maxwellDifferentialFluxGrid(n, vb, vth, elist, tlist, plist) >>> print('{:.2f}'.format( diff_flux.data.max())) 68765.73
Now the
diff_flux
is an object ofirfpy.util.energyspectrum.DifferentialFluxGrid
Giving the g-factor of 1e-5 cm2 sr eV/eV, you may get the count rate object (
irfpy.util.energyspectrum.CountRateGrid
object).>>> cps = dflx2cnt_simple_convfact(diff_flux, 1e-5) >>> print('{:.1f}'.format(cps.cps.max())) 440.1
If the g-factor has energy dependence, and you have g-factor array, you may need to make a g-factor array to be (nEne, nPol, nAz) shape.
>>> gfactor = np.array([1, 2, 3, 4, 5, 5, 4, 3, 2, 1]) * 1e-5 >>> gfactor_3d = nptools.broadcast_r(gfactor, [10, 6, 8]) >>> print(gfactor_3d.shape) (10, 6, 8) >>> cps = dflx2cnt_simple_convfact(diff_flux, gfactor_3d) >>> print('{:.1f}'.format(cps.cps.max())) 1760.4
The inversion function is also prepared as
cnt2dflx_simple_convfact()
.>>> dflx2 = cnt2dflx_simple_convfact(cps, gfactor_3d)
The results should be (almost) identical.
>>> diff = dflx2.dflux - diff_flux.dflux >>> print('{:.10f}'.format((diff ** 2).max())) 0.0000000000
- irfpy.util.fluxtools.fit_differential_flux_by_maxwell(diff_flux, log=False, initial_params=None, method='L-BFGS-B')[source]¶
Fit the energy spectrum by Maxwellian using least-square method.
- Parameters:
diff_flux (
irfpy.util.energyspectrum.DifferentialFluxGrid
) – Differential flux.log – If specified, the fitting is done in the log-space (not yet implemented)
initial_params – You may specify this as a tuple. (density_cc, vx_km/s, vy_km/s, vz_km/s, vth_km/s) If
None
is given, the initial parameters are calculated from moment calculations with proton assumed. (irfpy.util.energyspectrum.DifferentialFluxGrid.density()
,irfpy.util.energyspectrum.DifferentialFluxGrid.velocity_vector()
,irfpy.util.energyspectrum.DifferentialFluxGrid.pressure_tensor()
)method – Method for
scipy.optimize.minimize
. Default is ‘L-BFGS-B’.
- Author:
Yoshifumi Futaana
>>> estep = [10, 20, 40, 80, 160, 320, 640, 1280, 2560, 5120, 10240, 20480] >>> tstep = np.deg2rad([22.5, 45, 67.5, 90, 112.5, 135, 157.5]) >>> pstep = np.deg2rad([0, 30, 60, 90, 120, 150, 180, 210, 240, 270, 300, 330]) >>> maxwell_flux = energyspectrum.maxwellDifferentialFluxGrid( ... 10e6, [400e3, 100e3, -50e3], 200e3, ... estep, tstep, pstep) >>> fit = fit_differential_flux_by_maxwell(maxwell_flux) >>> print('{:.1f} {:.1f} {:.1f} {:.1f} {:.1f}'.format(fit[0], fit[1], fit[2], fit[3], fit[4])) 10.0 400.0 100.0 -50.0 200.0