"""Array convention to pass indices to cell positions.
ECLAIRs general program pipeline convention (yzegp) of 2D array:
=============================================================
yzegp used cartesian convention where :
* first coordinate is the position on horizontal axis, same as y axis in ECL_Los frame
defined by CNES
* second coordinate is the position on vertical axis, same as z axis in ECL_Los frame
defined by CNES
* so shield ECLAIRs is at the bottom and origin of epg is always in left corner
* the value is associated to "pixel" that has the lower left corner at (y,z)
.. note::
Cartesian convention is use everywhere in ecpi library.
Mainly used with class :py:class:`.ArraySquareCell`
to define sub-mask and detector geometry :py:class:`.InstruECLAIRs` in ECL_Los frame
example : a_epg[1,2] = 1
::
z axis (same direction that z_ECCLos)
^
|
|
3 + +-+
| |1|
2 + +-+
|
1 +
|
0 +-+-+-+----> y axis (same direction that y_ECCLos)
0 1 2 3
+---------------------+
| SHIELD ECLAIRs |
+---------------------+
ijDet convention of 2D array:
=============================
ijDet used row, column convention where :
* 'i' first coordinate is the row number along direction like z axis in ECLLos frame defined by CNES
* 'j' second coordinate is the column number along direction like inverse of y axis in ECLLos frame
defined by CNES
* so shield ECLAIRs is at the bottom and origin of ijDet is always in right corner
Example : a_epg[1,2] = 1
::
i
^
| 2
+-+ +
|1| | 1
+-+ +
| 0
j <----+-+-+-+
2 1 0
+---------------------+
| SHIELD ECLAIRs |
+---------------------+
.. note::
ijDet is only use for input and output data file requiring an "array detector convention"
"""
import numpy as np
import matplotlib.pyplot as plt
#
# on index
#
[docs]def ijdet_to_yzegp(idet, jdet, idx_max=79):
"""convert couple index in ijdet convention to yzegp convention
:param idet: first coordinate of ijdet
:type idet: integer
:param jdet: second coordinate of ijdet
:type jdet: integer
:param idx_max: index max (ie MAX-1)
:type idx_max: integer
"""
return idx_max - jdet, idet
[docs]def yzegp_to_ijdet(y_gp, z_gp, idx_max=79):
"""convert couple index in yzegp convention to ijdet convention
:param y_gp: first coordinate of yzegp
:type y_gp: integer
:param z_gp: second coordinate of yzegp
:type z_gp:integer
:param idx_max: index max (ie MAX-1)
:type idx_max:integer
"""
return z_gp, idx_max - y_gp
#
# from array ijdet
#
[docs]def ijdet_to_yzegp_array_slow(a_ijdet):
"""convert array 2D in ijdet convention to yzegp convention
:param a_ijdet: array in ijdet convention
:type a_ijdet: numpy 2D array
"""
out_array = np.empty_like(a_ijdet)
in_shape = a_ijdet.shape
# only square array
assert in_shape[0] == in_shape[1]
dim = in_shape[0]
for idx_i in range(dim):
for idx_j in range(dim):
idx_out = ijdet_to_yzegp(idx_i, idx_j, dim - 1)
out_array[idx_out] = a_ijdet[idx_i, idx_j]
return out_array
[docs]def ijdet_to_yzegp_array(a_ijdet):
"""convert array 2D in ijdet convention to yzegp convention
:param a_ijdet: array in ijdet convention
:type a_ijdet: numpy 2D array
"""
# this transformation is ok too np.flip(np.transpose(a_ijdet), 0)
return np.rot90(a_ijdet)
#
# from array yzegp
#
[docs]def yzegp_to_ijdet_array(a_gpidx):
"""convert array 2D in yzegp convention to ijdet convention
:param a_gpidx: array in yzegp convention
:type a_gpidx: numpy 2D array
"""
return np.flip(a_gpidx, 0).transpose()
#
# functions using ndet convention
#
# TODO: tests exhaustifs of the orientation of NDET convention
[docs]def ndet_to_ijdet(ndet, idx_max=79):
""" Convert coordinate in ndet convention to ijdet convention
Parameters
----------
ndet : integer [0, 6399]
pixel number in the NDET system
idx_max : integer
index maximum (i.e MAX - 1)
Returns
-------
integer
first coordinate of the ijdet system
integer
second coordinate of the ijdet system
"""
return ndet // (idx_max + 1), ndet % (idx_max + 1)
[docs]def ijdet_to_ndet(idet, jdet, idx_max=79):
"""Convert coordinate in ijdet convention to ndet convention
Parameters
----------
idet : integer
first coordinate of the ijdet system
jdet : integer
second coordinate of the ijdet system
idx_max : integer
index maximum (i.e MAX - 1)
Returns
-------
integer [0, 6399]
pixel number in the NDET system
"""
return (idx_max + 1) * idet + jdet
[docs]def ndet_to_yzegp(ndet, idx_max=79):
""" Convert coordinate in ndet convention to yzegp convention
Parameters
----------
ndet : integer [0, 6399]
pixel number in the NDET system
idx_max :
index maximum (i.e MAX - 1)
Returns
-------
integer
first coordinate of the yzegp system
integer
second coordinate of the yzegp system
"""
return idx_max - (ndet % (idx_max + 1)), ndet // (idx_max + 1)
[docs]def yzegp_to_ndet(yegp, zegp, idx_max=79):
"""Convert couple index in yzegp convention to ndet convention
Parameters
----------
yegp : integer
first coordinate of the yzegp system
zegp : integer
second coordinate of the yzegp system
idx_max : integer
index maximum (i.e MAX - 1)
Returns
-------
integer [0, 6399]
pixel number in the NDET system
"""
return (idx_max + 1) * zegp - yegp + idx_max
#
# from ndet vector to ijdet and yzegp arrays
#
[docs]def ndet_to_yzegp_array(ndet):
""" Convert ndet array into a matrix in yzegp convention
Parameters
----------
ndet : array [0, 6399]
pixel list (or 1d array) in NDET format
Returns
-------
matrix
pixel matrix in the the yzegp system
"""
if type(ndet) == list:
ndet = np.array(ndet, dtype=float)
return ndet.reshape(80, 80)
[docs]def yzegp_to_ndet_array(yzegp):
"""Convert yzegp pixel matrix into a ndet vector
Parameters
----------
yzegp : float matrix (80,80)
pixel matrix in the yzegp system
Returns
-------
1d array [0, 6399]
pixel number in the NDET system
"""
if type(yzegp) == list:
yzegp = np.array(yzegp, dtype=float)
# return np.ravel(yzegp, order='F')
return np.ravel(yzegp, order='C')
[docs]def plot_ijdet(array_yzegp, mes=""): # pragma: no cover
"""
:param array_yzegp: in ecpi convention (see below)
:param mes: message for title
"""
plt.figure()
plt.title("*[RADIATOR] " + mes)
plt.imshow(yzegp_to_ijdet_array(array_yzegp))
plt.colorbar()
plt.xlabel("j det")
plt.ylabel("i det")
[docs]def plot_ecllos(array_yzegp, mes=""): # pragma: no cover
"""
:param array_yzegp: in ecpi convention (see below)
:param mes: message for title
"""
plt.figure()
plt.title(mes)
plt.imshow(np.transpose(array_yzegp), origin='lower')
plt.colorbar()
plt.xlabel("y_egp (like Y ECLLos) [RADIATOR]*")
plt.ylabel("z_egp (like Z ECLLos)")