irfpy.mima.ghostbuster

Handling proton ghost.

Proton ghost is a problem for MEX data handling. This module provide an algorithm to reduce the ghost.

Usage: To be written.

Algorithm: The algorithm used is based on Hans’ implementation of Matlab. Some modifications have been done (both intentionally and unintentionally), but I hope general tendency is kept.

There are 7 rules defined by Hans, but so far three of simple rules have been implemented (Rules 2, 3, and 4).

The reduction is done for (E96,M32) matrix.

Usually, the matrix should already be corrected by - background subtraction - missing mass interpolation - masking the blocked FOV but more detailed explanations should be written.

irfpy.mima.ghostbuster.maximax(arr1d)[source]

Return a pair of (max, maxarg) for arr1d.

Parameters

arr1d – 1-dimensional array

Returns

(max, maxarg)

irfpy.mima.ghostbuster.minimin(arr1d)[source]
irfpy.mima.ghostbuster.indexes_energy_at(etable, energy)[source]

Return the index pair where the given energy bisect.

Parameters
  • etable – Energy array, nan allowed

  • energy – Enegy

Returns

(i0, i1) where etable[i0] > energy > etable[i1] (To check which contains the equal, but not very sensitive)

>>> from irfpy.mima import energy
>>> import numpy as np
>>> etable = energy.get_default_table_v5_late(negative=True)
>>> etable = np.where(etable > 0, etable, np.nan)
>>> i0, i1 = indexes_energy_at(etable, 200)
>>> print(i0, etable[i0])
49 215.7
>>> print(i1, etable[i1])
50 193.0
irfpy.mima.ghostbuster.increment(value, by=1, max=inf, min=- inf)[source]

A helper function to increment (and to decrement)

Parameters
  • value – The original value

  • by – A value to add to the original. Default of 1 is increment. If you specify -1, it corresponds to decrement.

  • max – Maximum of possible value

  • min – Minimum of possible value

Returns

value + by is returned. If it exceed max, max is returned. If it becomes below min, min is returned.

class irfpy.mima.ghostbuster.BusterBase(emmatrix, lowenergy_limit_eV=100, highenergy_limit_eV=2000)[source]

Bases: object

Parameters
  • emmatrix

  • lowenergy_limit_eV

  • highenergy_limit_eV

  • delta

  • lim

increment(i)[source]

Increment.

Parameters

i – Original value

Returns

Incremented value, i+1, or self.max_estep if i+1>self.max_estep

>>> import numpy as np
>>> emmatrix = EMmatrix(np.zeros([96,32]), 15, 4)   # prom=15 and pacc=4
>>> bbase = BusterBase(emmatrix, lowenergy_limit_eV=200)
>>> print(bbase.increment(30))
31
>>> print(bbase.max_estep)
49
>>> print(bbase.increment(49))   # It does not go to 50, but is kept 49
49
decrement(i)[source]

Decrement.

Parameters

i – Original value

Returns

Decremented value, i-1, or self.min_estep if i-1 < max.minstep.

>>> import numpy as np
>>> emmatrix = EMmatrix(np.zeros([96,32]), 15, 4)   # prom=15 and pacc=4
>>> bbase = BusterBase(emmatrix, highenergy_limit_eV=1000)
>>> print(bbase.decrement(40))
39
>>> print(bbase.min_estep)
31
>>> print(bbase.decrement(30))   # It does not go to 29, but goes to 31
31
split_proton()[source]

Split the self.original EMmatrix to two EMmatrixes. Proton and Nonproton.

Returns

get_noproton_matrix()[source]
split_energy_range_noproton(e0, e1)[source]

Split the self.original EMmatrix to two EMmatrixes. Inside or outside the energy step range [e0,e1]

Parameters
  • e0

  • e1

Returns

A pair of EMmatrix, inside matrix and outside matrix

buster()[source]
Returns

A pair of EMmatrix (em1, em2). em1 is for the cleaned matrix, and em2 is for the matrix that was subtracted.

class irfpy.mima.ghostbuster.BusterSingleEnergySpillover(*args, **kwds)[source]

Bases: irfpy.mima.ghostbuster.BusterBase

Parameters
  • emmatrix

  • lowenergy_limit_eV

  • highenergy_limit_eV

  • delta

  • lim

buster(lim=14, delta=3, minimum_ratio_heavy_middle=5, minimum_ratio_ghost_proton=2)[source]
Returns

A pair of EMmatrix (em1, em2). em1 is for the cleaned matrix, and em2 is for the matrix that was subtracted.

class irfpy.mima.ghostbuster.BusterSpillOverManyNonzeros(*args, **kwds)[source]

Bases: irfpy.mima.ghostbuster.BusterBase

Parameters
  • emmatrix

  • lowenergy_limit_eV

  • highenergy_limit_eV

  • delta

  • lim

buster(threshold=28, m0=0, m1=31)[source]

Buster the spill over.

Parameters

threshold – Threshold. If more than this number between [m0,m1], this rule is triggered.

Returns

a pair of EMmatrix

If many mass channel is occupied, this condition is triggered.

For example, let’s try to make the following array.

>>> import numpy as np
>>> matrix = np.zeros([96, 32])
>>> matrix[40, :] = 1    # E=40, all the data is 1.  Total 32.
>>> matrix[39, 3:-3] = 2   # E=39 , the data is 2. Total 2x26 = 52
>>> matrix[38, 6:-6] = 3   # E=38, the data is 3. Total 3x20 = 60
>>> matrix[37, 9:-9] = 4   # E=37, the data is 4. Total 4x14 = 56
>>> matrix[36, 12:-12] = 5 # #=36, the data is 5. Total 5x8 = 40
>>> matrix[35, 15:-15] = 6  # E=35, the data is 6, total, 6x2 = 12
>>> matrix[41, 3:-3] = 2   # E=39 , the data is 2. Total 2x26 = 52
>>> matrix[42, 6:-6] = 3   # E=38, the data is 3. Total 3x20 = 60
>>> matrix[43, 9:-9] = 4   # E=37, the data is 4. Total 4x14 = 56
>>> matrix[44, 12:-12] = 5 # #=36, the data is 5. Total 5x8 = 40
>>> matrix[45, 15:-15] = 6  # E=35, the data is 6, total, 6x2 = 12
>>> emmatrix = EMmatrix(matrix, 15, 4)
>>> buster_matrix = BusterSpillOverManyNonzeros(emmatrix)
>>> m1, m2 = buster_matrix.buster()
class irfpy.mima.ghostbuster.BusterWeakSolarwind(*args, **kwds)[source]

Bases: irfpy.mima.ghostbuster.BusterBase

Parameters
  • emmatrix

  • lowenergy_limit_eV

  • highenergy_limit_eV

  • delta

  • lim

buster()[source]

Buster weak SW

Returns

class irfpy.mima.ghostbuster.BusterTooManyCountInMiddle(*args, **kwds)[source]

Bases: irfpy.mima.ghostbuster.BusterBase

Criteria 6. If too many counts exist in amu 5-12 area, the count <5 amu to be ghost

Parameters
  • emmatrix

  • lowenergy_limit_eV

  • highenergy_limit_eV

  • delta

  • lim

buster(threshould=10.0)[source]

Buster the ghost.

Parameters

threshould – The threshold, k.

Return type

(EMmatrix, EMmatrix)

Returns

A pair of matrix. Real and ghost matrixes.

We use the following rule for each energy step in the ghost energy range (defined in __init__ as parameter).

Calculate

  • <Cmiddle>, a median count in the middle mass channel (mass 5-12 amu)

  • <Cheavy>, a median count in the heavy mass channel (mass 12 and above)

Then, if <Cmiddle> > <Cheavy> / k, then this rule is activated.

The rule will then consider the counts at mass 5 amu and above as ghost.

class irfpy.mima.ghostbuster.BusterTooManyCountInLowMassChannels(*args, **kwds)[source]

Bases: irfpy.mima.ghostbuster.BusterBase

Criteria 7. If too many counts in low mass channel than middle (5-12).

Parameters
  • emmatrix

  • lowenergy_limit_eV

  • highenergy_limit_eV

  • delta

  • lim

buster(threshold=2)[source]
Returns

A pair of EMmatrix (em1, em2). em1 is for the cleaned matrix, and em2 is for the matrix that was subtracted.

class irfpy.mima.ghostbuster.EMmatrix(emmatrix: numpy.ndarray, promsection: int, pacc: int)[source]

Bases: object

Energy-Mass matrix data & associated table.

Making EMmatrix by hand.

>>> import numpy as np
>>> em = np.arange(96)[:, np.newaxis] + np.zeros([96, 32])    # (96, 32) array, with energy index as value
>>> em[85:] = np.nan
>>> matx = EMmatrix(em, 15, 4)

Getting data.

>>> em1 = matx.get_matrix()    # Just return the matrix. Should be the same to em
>>> (em == em1)[:85].all()
True

Collapsing the matrix.

>>> espect = matx.get_max_energy_spectra()    # Energy spectra, maximum along mass.
>>> espect[30]    # As defined above, it should be the index.
30.0
>>> mspect = matx.get_max_mass_spectra()    # Mass spectra. This case, constantly 84.
>>> mspect[15]
84.0
>>> espect = matx.get_sum_energy_spectra()
>>> espect[10]   # Sum shall be the index time 32.
320.0
>>> mspect = matx.get_sum_mass_spectra()
>>> mspect[10]   # Sum shall be constantly the sum from 0 to 84.
3570.0
Parameters
  • emmatrix (numpy.ndarray) – E-M matrix with (96, 32) shape.

  • promsection – PROM section. 0 to 16.

  • pacc – PACC. 0 to 7.

  • acceptance_proton – Acceptance mass channel for protons. mass channel > Rm + Dm * acceptace_proton is considered as real proton.

>>> em = EMmatrix(_np.zeros([96, 32]), 16, 4)
emmatrix

The E-M matrix.

get_matrix(*args, **kwds)[source]
get_sum_energy_spectra()[source]
get_sum_mass_spectra()[source]
get_max_energy_spectra()[source]
get_max_mass_spectra()[source]
get_nonzero_count_mass_spectrum()[source]

Return the number of nonzero energy step for each mass channel.

Returns

Number of nonzero energy step for each mass channel. (32,) shaped

get_nonzero_count_energy_spectrum(m0=0, m1=31)[source]

Return the number of nonzero mass channels for each energy step.

Returns

Number of nonzero mass channel for each energy step. (96,) shaped

split(condition)[source]

Return two new EMmatrix, which do and do not satisfy condition

Parameters

condition – (96,32) shaped bool array

Returns

(m1, m2) where both m1 and m2 is :class`EMmatrix` object. m1 contains bins where condtions are True, and m2 for bins where condtions are False. Otherwise, 0 are filled. (nan is kept)

>>> import numpy as np
>>> em = np.arange(96)[:, np.newaxis] + np.zeros([96, 32])    # (96, 32) array, with energy index as value
>>> em[85:] = np.nan
>>> matx = EMmatrix(em, 15, 4)
>>> meven, modd = matx.split(matx.get_matrix() % 2 == 0)     # Select even values to meven and otherwise modd
>>> print(np.nanmax(meven.get_matrix()))
84.0
>>> print(np.nanmax(modd.get_matrix()))
83.0
>>> print(np.nansum(meven.get_matrix()))    # sum of 2 to 84 is 1806, multiplied by 32 => 57792
57792.0
>>> (modd.get_matrix() + meven.get_matrix() == matx.get_matrix())[:85].all()    # Sum of two results shall be the original.
True
>>> np.isfinite(modd.get_matrix()[85:]).any()   # All the data E>=85 should not be a finite number.
False
ascii_dump(fp=None)[source]

Ascii dump

>>> import numpy as np
>>> arr = np.random.poisson(0.2, size=(96,32))
>>> em = EMmatrix(arr, 15, 4)
>>> em.ascii_dump()      
zeros_like()[source]

Produce a new EMmatrix, with matrix filled by zero.

Returns

Zero-filled EMmatrix. Other parameters are the same as self.

>>> import numpy as np
>>> em = np.arange(96)[:, np.newaxis] + np.zeros([96, 32])    # (96, 32) array, with energy index as value
>>> em[85:] = np.nan
>>> matx = EMmatrix(em, 15, 4)
>>> zeromatx = matx.zeros_like()
>>> print(zeromatx.emmatrix.max())
0.0
>>> print(zeromatx.pacc)
4
>>> print(zeromatx.promsection)
15
irfpy.mima.ghostbuster.buster_rule1(emmatrix: irfpy.mima.ghostbuster.EMmatrix)[source]
irfpy.mima.ghostbuster.buster_rule2(emmatrix: irfpy.mima.ghostbuster.EMmatrix)[source]
irfpy.mima.ghostbuster.buster_rule3(emmatrix: irfpy.mima.ghostbuster.EMmatrix)[source]
irfpy.mima.ghostbuster.buster_rule4(emmatrix: irfpy.mima.ghostbuster.EMmatrix)[source]
irfpy.mima.ghostbuster.buster_rule5(emmatrix: irfpy.mima.ghostbuster.EMmatrix)[source]
irfpy.mima.ghostbuster.buster_rule6(emmatrix: irfpy.mima.ghostbuster.EMmatrix)[source]
irfpy.mima.ghostbuster.buster_rule7(emmatrix: irfpy.mima.ghostbuster.EMmatrix)[source]
irfpy.mima.ghostbuster.condition_estep_range(estep0, estep1)[source]

Make a condition matrix.

Parameters
  • estep0 – Minimum energy step. Inclusive.

  • estep1 – Maximum energy step. Inclusive.

Returns

Bool array of (96,32), with [estep0:estep1+1, :] as True, otherwise false.

>>> cond = condition_estep_range(30, 50)
>>> cond.shape
(96, 32)
>>> print(cond[30, :].all())   # Estep-30 is True for all
True
>>> print(cond[50, :].all())   # Estep=50 is True for all
True
>>> print(cond[29, :].any())   # Estep-29 is False for all
False
>>> print(cond[51, :].any())   # Estep=51 is false for all
False
class irfpy.mima.ghostbuster.MassFilter(promsection, pacc)[source]

Bases: object

Handles mass in the EM matrix.

rm(m)[source]
dm(m)[source]
massline_proton_minimum(acceptance_proton=2.0)[source]
condition_real_proton(acceptance_proton=2.0)[source]

Return a bool array specifying the real proton

Returns

(96,32) bool array. True for the real proton, False for non-trivial proton.

>>> filter = MassFilter(15, 4)
>>> matx = filter.condition_real_proton()
>>> matx.shape
(96, 32)
>>> print(matx[19, 24:26])    # Energy step 17, Mass step 24 is False, but 25 is True
[False  True]
>>> print('%.2f' % filter.massline_proton_minimum()[19])   # ... as the minimum proton line sits 24.63.
24.63
condition_shouldbemin(m0=5, m1=12)[source]

shouldbemin parameter by HN.

My understanding is that this area no much foregound is expected, so that ghost dominates.

Parameters
  • m0 – Lowest mass in amu

  • m1 – Highest mass in amu

Returns

A conditon matrix (96, 32)

irfpy.mima.ghostbuster.simple_plotting(em: numpy.ndarray, title='')[source]

Simple plotting.

Parameters

em – (96, 32) array.