Skip to content

Commit ea1c4dd

Browse files
committed
[#1166] plot_xray_thin_d2cross_ei_anisotropy(d2cross=pfe, dcases=str) operational
1 parent da504ff commit ea1c4dd

File tree

2 files changed

+193
-90
lines changed

2 files changed

+193
-90
lines changed
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
2+
# ANISOTROPY CASES
3+
_DCASES_PRE = {
4+
5+
# -------------
6+
# standard span
7+
8+
'standard': {
9+
0: {
10+
'E_e0_eV': 20e3,
11+
'E_ph_eV': 10e3,
12+
'color': 'r',
13+
'marker': '*',
14+
'ms': 14,
15+
},
16+
1: {
17+
'E_e0_eV': 100e3,
18+
'E_ph_eV': 50e3,
19+
'color': 'c',
20+
'marker': '*',
21+
'ms': 14,
22+
},
23+
2: {
24+
'E_e0_eV': 100e3,
25+
'E_ph_eV': 10e3,
26+
'color': 'm',
27+
'marker': '*',
28+
'ms': 14,
29+
},
30+
3: {
31+
'E_e0_eV': 1000e3,
32+
'E_ph_eV': 10e3,
33+
'color': (0.8, 0.8, 0),
34+
'marker': '*',
35+
'ms': 14,
36+
},
37+
4: {
38+
'E_e0_eV': 10000e3,
39+
'E_ph_eV': 10e3,
40+
'color': (0., 0.8, 0.8),
41+
'marker': '*',
42+
'ms': 14,
43+
},
44+
5: {
45+
'E_e0_eV': 1000e3,
46+
'E_ph_eV': 50e3,
47+
'color': (0.8, 0., 0.8),
48+
'marker': '*',
49+
'ms': 14,
50+
},
51+
},
52+
53+
# ------------------
54+
# large span
55+
56+
'span_100eV_10MeV': {
57+
0: {
58+
'E_e0_eV': 20e3,
59+
'E_ph_eV': 10e3,
60+
'color': 'r',
61+
'marker': '*',
62+
'ms': 14,
63+
},
64+
1: {
65+
'E_e0_eV': 100e3,
66+
'E_ph_eV': 50e3,
67+
'color': 'c',
68+
'marker': '*',
69+
'ms': 14,
70+
},
71+
},
72+
}

tofu/physics_tools/electrons/emission/_xray_thin_target_integrated_plot.py

Lines changed: 121 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515

1616
from . import _xray_thin_target_integrated as _mod
17+
from ._xray_thin_target_integrated_cases import _DCASES_PRE
1718

1819

1920
TupleDict = tuple[dict]
@@ -34,59 +35,26 @@
3435

3536
# DSCALES
3637
_DSCALES = {
37-
'E_ph': 'linear',
38+
'E_ph': 'log',
3839
'E_e0': 'log',
3940
'theta': 'linear',
4041
}
4142

4243

43-
# ANISOTROPY CASES
44-
_DCASES = {
45-
0: {
46-
'E_e0_eV': 20e3,
47-
'E_ph_eV': 10e3,
48-
'color': 'r',
49-
'marker': '*',
50-
'ms': 14,
51-
},
52-
1: {
53-
'E_e0_eV': 100e3,
54-
'E_ph_eV': 50e3,
55-
'color': 'c',
56-
'marker': '*',
57-
'ms': 14,
58-
},
59-
2: {
60-
'E_e0_eV': 100e3,
61-
'E_ph_eV': 10e3,
62-
'color': 'm',
63-
'marker': '*',
64-
'ms': 14,
65-
},
66-
3: {
67-
'E_e0_eV': 1000e3,
68-
'E_ph_eV': 10e3,
69-
'color': (0.8, 0.8, 0),
70-
'marker': '*',
71-
'ms': 14,
72-
},
73-
4: {
74-
'E_e0_eV': 10000e3,
75-
'E_ph_eV': 10e3,
76-
'color': (0., 0.8, 0.8),
77-
'marker': '*',
78-
'ms': 14,
79-
},
80-
5: {
81-
'E_e0_eV': 1000e3,
82-
'E_ph_eV': 50e3,
83-
'color': (0.8, 0., 0.8),
84-
'marker': '*',
85-
'ms': 14,
86-
},
44+
# ANISOTROPY CASES FORMATTING
45+
_DCASES_FORMAT = {
46+
'E_e0_eV': (int, float),
47+
'E_ph_eV': (int, float),
48+
'color': (str, tuple),
49+
'marker': str,
50+
'ms': (int, float),
8751
}
8852

8953

54+
# ANISOTROPY CASES DEFAULT
55+
_DCASES_CASE = 'standard'
56+
57+
9058
# ####################################################
9159
# ####################################################
9260
# plot anisotropy
@@ -146,7 +114,6 @@ def plot_xray_thin_d2cross_ei_anisotropy(
146114
(
147115
E_e0_eV, E_ph_eV, theta_ph,
148116
version,
149-
dcases,
150117
dscales,
151118
verb,
152119
fontsize,
@@ -175,6 +142,22 @@ def plot_xray_thin_d2cross_ei_anisotropy(
175142
verb=verb,
176143
)
177144

145+
# -------------------
146+
# update from d2cross
147+
# -------------------
148+
149+
# if d2cross was provided
150+
theta_ph = d2cross['theta_ph']['data'].ravel()
151+
E_ph_eV = d2cross['E_ph']['data'].ravel()
152+
E_e0_eV = d2cross['E_e0']['data'].ravel()
153+
154+
# dcases
155+
dcases = _check_dcases(
156+
dcases=dcases,
157+
E_e0_eV=E_e0_eV,
158+
E_ph_eV=E_ph_eV,
159+
)
160+
178161
# --------------
179162
# prepare axes
180163
# --------------
@@ -205,14 +188,18 @@ def plot_xray_thin_d2cross_ei_anisotropy(
205188
theta_ph*180/np.pi,
206189
axis=0,
207190
)
191+
mean_log10 = np.full(mean.shape, np.nan)
192+
iok = np.isfinite(mean)
193+
iok[iok] = mean[iok] > 0.
194+
mean_log10[iok] = np.log10(mean[iok])
208195
mean_units = vv['units']
209196

210197
# integral
211198
if dplot_mean is not False:
212199
im0 = ax.contour(
213200
E_e0_eV * 1e-3,
214201
E_ph_eV * 1e-3,
215-
np.log10(mean).T,
202+
mean_log10.T,
216203
levels=dplot_mean['levels'],
217204
colors=dplot_mean['colors'],
218205
)
@@ -315,7 +302,8 @@ def plot_xray_thin_d2cross_ei_anisotropy(
315302
)
316303

317304
# limits
318-
ax.set_ylim(0, ymax*1e-3)
305+
if dscales['E_ph'] == 'linear':
306+
ax.set_ylim(0, ymax*1e-3)
319307

320308
# ---------------
321309
# plot - cases
@@ -389,8 +377,6 @@ def _check_anisotropy(
389377
E_ph_eV=None,
390378
theta_ph=None,
391379
version=None,
392-
# selected cases
393-
dcases=None,
394380
# verb
395381
verb=None,
396382
# scales
@@ -437,38 +423,6 @@ def _check_anisotropy(
437423
if version is None:
438424
version = _VERSION
439425

440-
# ------------
441-
# dcases
442-
# ------------
443-
444-
ddef = copy.deepcopy(_DCASES)
445-
if dcases in [None, True]:
446-
dcases = ddef
447-
448-
if dcases is not False:
449-
for k0, v0 in dcases.items():
450-
dcases[k0] = _check_anisotropy_dplot(
451-
v0,
452-
f'dcases[{k0}]',
453-
ddef[0],
454-
)
455-
456-
# update with indices
457-
ie = np.argmin(np.abs(E_e0_eV - dcases[k0]['E_e0_eV']))
458-
iph = np.argmin(np.abs(E_ph_eV - dcases[k0]['E_ph_eV']))
459-
dcases[k0].update({'ie': ie, 'iph': iph})
460-
461-
# update with label
462-
ee0 = E_e0_eV[ie]
463-
eph = E_ph_eV[iph]
464-
dcases[k0]['lab'] = (
465-
r"$E_{e0} / E_{ph}$ = "
466-
+ f"{ee0*1e-3:3.0f} / {eph*1e-3:3.0f} keV = "
467-
+ f"{round(ee0 / eph, ndigits=1)}"
468-
)
469-
else:
470-
dcases = {}
471-
472426
# -----------
473427
# verb
474428
# -----------
@@ -545,14 +499,76 @@ def _check_anisotropy(
545499
return (
546500
E_e0_eV, E_ph_eV, theta_ph,
547501
version,
548-
dcases,
549502
dscales,
550503
verb,
551504
fontsize,
552505
dplot_forbidden, dplot_peaking, dplot_thetamax, dplot_mean,
553506
)
554507

555508

509+
def _check_dcases(
510+
dcases=None,
511+
E_e0_eV=None,
512+
E_ph_eV=None,
513+
):
514+
515+
# --------------
516+
# dcases default
517+
# --------------
518+
519+
ddef = copy.deepcopy(_DCASES_FORMAT)
520+
if dcases in [None, True]:
521+
dcases = _DCASES_CASE
522+
523+
# --------------
524+
# dcases from predefined
525+
# --------------
526+
527+
if isinstance(dcases, str):
528+
lok = sorted(_DCASES_PRE.keys())
529+
if dcases not in lok:
530+
lstr = [f"\t- {kk}" for kk in lok]
531+
msg = (
532+
"Arg 'dcases' must be either:\n"
533+
"\t- dict of cases\n"
534+
"\t- a key to a predefined dict of cases\n"
535+
"Available predefined dcases:\n"
536+
+ "\n".join(lstr)
537+
)
538+
raise Exception(msg)
539+
dcases = copy.deepcopy(_DCASES_PRE[dcases])
540+
541+
# --------------
542+
# generic check
543+
# --------------
544+
545+
if dcases is not False:
546+
for k0, v0 in dcases.items():
547+
dcases[k0] = _check_anisotropy_dplot(
548+
v0,
549+
f'dcases[{k0}]',
550+
ddef,
551+
)
552+
553+
# update with indices
554+
ie = np.argmin(np.abs(E_e0_eV - dcases[k0]['E_e0_eV']))
555+
iph = np.argmin(np.abs(E_ph_eV - dcases[k0]['E_ph_eV']))
556+
dcases[k0].update({'ie': ie, 'iph': iph})
557+
558+
# update with label
559+
ee0 = E_e0_eV[ie]
560+
eph = E_ph_eV[iph]
561+
dcases[k0]['lab'] = (
562+
r"$E_{e0} / E_{ph}$ = "
563+
+ f"{ee0*1e-3:3.0f} / {eph*1e-3:3.0f} keV = "
564+
+ f"{round(ee0 / eph, ndigits=1)}"
565+
)
566+
else:
567+
dcases = {}
568+
569+
return dcases
570+
571+
556572
def _check_anisotropy_dplot(din, dname, ddef):
557573

558574
# -------------
@@ -569,7 +585,11 @@ def _check_anisotropy_dplot(din, dname, ddef):
569585
if din is not False:
570586
c0 = (
571587
isinstance(din, dict)
572-
and all([kk in ddef.keys() for kk in din.keys()])
588+
and all([
589+
kk in ddef.keys()
590+
and isinstance(din[kk], ddef[kk])
591+
for kk in din.keys()
592+
])
573593
)
574594
if not c0:
575595
lstr = [f"\t- ''{k0}': {v0}" for k0, v0 in ddef.items()]
@@ -604,19 +624,30 @@ def _get_peaking(data, x, axis=None):
604624
# ----------
605625

606626
integ = scpinteg.trapezoid(data, x=x, axis=axis)
607-
shape_integ = tuple([
608-
1 if ii == axis else ss
609-
for ii, ss in enumerate(data.shape)
610-
])
611-
data_n = data / integ.reshape(shape_integ)
627+
shape_integ = list(data.shape)
628+
shape_integ[axis] = 1
629+
630+
data_n = np.full(data.shape, np.nan)
631+
iok = np.isfinite(integ)
632+
iok[iok] = integ[iok] > 0
633+
iokn = iok.nonzero()
634+
sli0 = list(iokn)
635+
sli1 = list(iokn)
636+
sli0.insert(axis, None)
637+
sli1.insert(axis, slice(None))
638+
data_n[tuple(sli1)] = data[tuple(sli1)] / integ[tuple(sli0)]
612639

613640
# ----------
614641
# get average
615642
# ----------
616643

617644
shape_x = tuple([-1 if ii == axis else 1 for ii in range(data.ndim)])
618645
xf = x.reshape(shape_x)
619-
x_avf = scpinteg.simpson(data_n * xf, x=x, axis=axis).reshape(shape_integ)
646+
x_avf = scpinteg.trapezoid(
647+
data_n * xf,
648+
x=x,
649+
axis=axis,
650+
).reshape(shape_integ)
620651
std = np.sqrt(scpinteg.simpson(data_n * (xf - x_avf)**2, x=x, axis=axis))
621652

622653
return integ/180, 1/std

0 commit comments

Comments
 (0)