From 0130eaa6ddbe407f2cd58c5bc2b411d2b2037923 Mon Sep 17 00:00:00 2001 From: Florian Le Bourdais Date: Thu, 3 Oct 2019 18:05:51 +0200 Subject: [PATCH 01/10] add a custom emissivity tutorial --- examples/tutorials/plot_custom_emissivity.py | 53 ++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 examples/tutorials/plot_custom_emissivity.py diff --git a/examples/tutorials/plot_custom_emissivity.py b/examples/tutorials/plot_custom_emissivity.py new file mode 100644 index 000000000..08f85e48e --- /dev/null +++ b/examples/tutorials/plot_custom_emissivity.py @@ -0,0 +1,53 @@ +""" +Computing a camera image with custom emissivity +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +This tutorial defines an emissivity that varies in space and computes the signal received by a camera using +this emissivity. +""" + +############################################################################### +# We start by loading a built-in `tofu` configuration and define a 2D camera. + +import numpy as np +import tofu as tf + +configB2 = tf.geom.utils.create_config("B2") + +cam2d = tf.geom.utils.create_CamLOS2D( + config=configB2, + P=[3.4, 0, 0], + N12=100, + F=0.1, + D12=0.1, + angs=[np.pi, 0, 0], + Name="", + Exp="", + Diag="", +) + + +############################################################################### +# Now, we define an emissivity function that depends on r and z coordinates. + +def emissivity(pts, t=None, vect=None): + """Custom emissivity as a function of geometry. + + pts is a tuple holding x, y, z geometry coordinates. + """ + r, z = np.hypot(pts[0, :], pts[1, :]), pts[2, :] + e = np.exp(-(r - 2.4) ** 2 / 0.2 ** 2 - z ** 2 / 0.2 ** 2) + if t is not None: + e = np.cos(np.atleast_1d(t))[:, None] * e[None, :] + return e + + +############################################################################### +# Finally, we compute an image using the 2D camera and this emissivity. We use the +# `plot=True` flag to obtain a graphical output. + +time_vector = np.linspace(0, 20, num=1000) + +sig, units = cam2d.calc_signal(emissivity, + resMode='abs', plot=True, + t=time_vector) From ca09e193142c76716c77d96e668d2c9c258aa32d Mon Sep 17 00:00:00 2001 From: Florian Le Bourdais Date: Thu, 3 Oct 2019 18:22:59 +0200 Subject: [PATCH 02/10] Update plot_custom_emissivity.py --- examples/tutorials/plot_custom_emissivity.py | 21 ++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/examples/tutorials/plot_custom_emissivity.py b/examples/tutorials/plot_custom_emissivity.py index 08f85e48e..11411ad60 100644 --- a/examples/tutorials/plot_custom_emissivity.py +++ b/examples/tutorials/plot_custom_emissivity.py @@ -8,6 +8,7 @@ ############################################################################### # We start by loading a built-in `tofu` configuration and define a 2D camera. +import matplotlib import numpy as np import tofu as tf @@ -26,9 +27,12 @@ Diag="", ) - ############################################################################### # Now, we define an emissivity function that depends on r and z coordinates. +# We can plot its profile in a section. + +import matplotlib.pyplot as plt + def emissivity(pts, t=None, vect=None): """Custom emissivity as a function of geometry. @@ -42,6 +46,18 @@ def emissivity(pts, t=None, vect=None): return e +y = np.linspace(-10, 10) +z = np.linspace(-10, 12) +Y, Z = np.meshgrid(y, z) +X = np.zeros_like(Y) +pts = np.c_[X.ravel(), Y.ravel(), Z.ravel()].T +emissivity_vals = emissivity(pts) +emissivity_vals = emissivity_vals.reshape(X.shape) + +fig, ax = plt.subplots() +ax.pcolormesh(emissivity_vals) +plt.show() + ############################################################################### # Finally, we compute an image using the 2D camera and this emissivity. We use the # `plot=True` flag to obtain a graphical output. @@ -49,5 +65,6 @@ def emissivity(pts, t=None, vect=None): time_vector = np.linspace(0, 20, num=1000) sig, units = cam2d.calc_signal(emissivity, - resMode='abs', plot=True, + resMode='abs', plot=False, t=time_vector) +sig.plot() \ No newline at end of file From e942045ea3f8f4aa01ecf3991f80ee44c8606b43 Mon Sep 17 00:00:00 2001 From: Florian Le Bourdais Date: Fri, 4 Oct 2019 17:47:12 +0200 Subject: [PATCH 03/10] Update plot_custom_emissivity.py better plots --- examples/tutorials/plot_custom_emissivity.py | 21 +++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/examples/tutorials/plot_custom_emissivity.py b/examples/tutorials/plot_custom_emissivity.py index 11411ad60..244fd157b 100644 --- a/examples/tutorials/plot_custom_emissivity.py +++ b/examples/tutorials/plot_custom_emissivity.py @@ -30,14 +30,19 @@ ############################################################################### # Now, we define an emissivity function that depends on r and z coordinates. # We can plot its profile in a section. - +import numpy as np import matplotlib.pyplot as plt def emissivity(pts, t=None, vect=None): """Custom emissivity as a function of geometry. - pts is a tuple holding x, y, z geometry coordinates. + + :param pts: ndarray of shape (3, n_points) (each column is a xyz coordinate) + :param t: optional, time parameter to add a time dependency to the emissivity function + :param vect: + :return: + - emissivity - array holding the emissivity for each point in the input grid """ r, z = np.hypot(pts[0, :], pts[1, :]), pts[2, :] e = np.exp(-(r - 2.4) ** 2 / 0.2 ** 2 - z ** 2 / 0.2 ** 2) @@ -46,8 +51,8 @@ def emissivity(pts, t=None, vect=None): return e -y = np.linspace(-10, 10) -z = np.linspace(-10, 12) +y = np.linspace(2, 3, num=90) +z = np.linspace(-0.5, 0.5, num=100) Y, Z = np.meshgrid(y, z) X = np.zeros_like(Y) pts = np.c_[X.ravel(), Y.ravel(), Z.ravel()].T @@ -55,16 +60,18 @@ def emissivity(pts, t=None, vect=None): emissivity_vals = emissivity_vals.reshape(X.shape) fig, ax = plt.subplots() -ax.pcolormesh(emissivity_vals) +ax.pcolormesh(Y, Z, emissivity_vals) +ax.set_xlabel('y') +ax.set_ylabel('z') plt.show() ############################################################################### # Finally, we compute an image using the 2D camera and this emissivity. We use the # `plot=True` flag to obtain a graphical output. -time_vector = np.linspace(0, 20, num=1000) +time_vector = np.linspace(0, 2 * np.pi, num=100) sig, units = cam2d.calc_signal(emissivity, - resMode='abs', plot=False, + resMode='rel', plot=False, t=time_vector) sig.plot() \ No newline at end of file From f23f7ebe61ab2db2b4d6b78f0fb68d420bf637f0 Mon Sep 17 00:00:00 2001 From: Florian Le Bourdais Date: Fri, 4 Oct 2019 17:52:19 +0200 Subject: [PATCH 04/10] Update plot_custom_emissivity.py --- examples/tutorials/plot_custom_emissivity.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/examples/tutorials/plot_custom_emissivity.py b/examples/tutorials/plot_custom_emissivity.py index 244fd157b..28f095245 100644 --- a/examples/tutorials/plot_custom_emissivity.py +++ b/examples/tutorials/plot_custom_emissivity.py @@ -8,7 +8,6 @@ ############################################################################### # We start by loading a built-in `tofu` configuration and define a 2D camera. -import matplotlib import numpy as np import tofu as tf @@ -30,7 +29,6 @@ ############################################################################### # Now, we define an emissivity function that depends on r and z coordinates. # We can plot its profile in a section. -import numpy as np import matplotlib.pyplot as plt From fe9a7bdb5c0baca8d988c8986c17e2c3c5f92a1f Mon Sep 17 00:00:00 2001 From: Florian Le Bourdais Date: Wed, 9 Oct 2019 17:07:26 +0200 Subject: [PATCH 05/10] update example for nicer plots --- examples/tutorials/plot_custom_emissivity.py | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/examples/tutorials/plot_custom_emissivity.py b/examples/tutorials/plot_custom_emissivity.py index 28f095245..b335339d6 100644 --- a/examples/tutorials/plot_custom_emissivity.py +++ b/examples/tutorials/plot_custom_emissivity.py @@ -28,14 +28,13 @@ ############################################################################### # Now, we define an emissivity function that depends on r and z coordinates. -# We can plot its profile in a section. +# We can plot its profile in the (0, X, Z) plane. import matplotlib.pyplot as plt def emissivity(pts, t=None, vect=None): """Custom emissivity as a function of geometry. - :param pts: ndarray of shape (3, n_points) (each column is a xyz coordinate) :param t: optional, time parameter to add a time dependency to the emissivity function :param vect: @@ -43,7 +42,7 @@ def emissivity(pts, t=None, vect=None): - emissivity - array holding the emissivity for each point in the input grid """ r, z = np.hypot(pts[0, :], pts[1, :]), pts[2, :] - e = np.exp(-(r - 2.4) ** 2 / 0.2 ** 2 - z ** 2 / 0.2 ** 2) + e = np.exp(-(r - 2.4) ** 2 / 0.2 ** 2 - z ** 2 / 0.4 ** 2) if t is not None: e = np.cos(np.atleast_1d(t))[:, None] * e[None, :] return e @@ -57,19 +56,26 @@ def emissivity(pts, t=None, vect=None): emissivity_vals = emissivity(pts) emissivity_vals = emissivity_vals.reshape(X.shape) +def project_to_2D(xyz): + """Projection to (0, X, Z) plane.""" + return xyz[0], xyz[2] + fig, ax = plt.subplots() ax.pcolormesh(Y, Z, emissivity_vals) ax.set_xlabel('y') ax.set_ylabel('z') -plt.show() +configB2.plot(lax=ax, proj='cross') +cam_center, = ax.plot(*project_to_2D(cam2d._dgeom['pinhole']), '*', ms=20) +ax.legend(handles=[cam_center], labels=['camera pinhole'], loc='upper right') ############################################################################### -# Finally, we compute an image using the 2D camera and this emissivity. We use the -# `plot=True` flag to obtain a graphical output. +# Finally, we compute an image using the 2D camera and this emissivity. If we provide a time vector, the field +# will vary in a cosinusoidal fashion (see above definition) across time. time_vector = np.linspace(0, 2 * np.pi, num=100) sig, units = cam2d.calc_signal(emissivity, resMode='rel', plot=False, t=time_vector) -sig.plot() \ No newline at end of file +sig.plot(ntMax=1) +plt.show() \ No newline at end of file From 7030392198e24af239e7d963a06d80a7bd6a7061 Mon Sep 17 00:00:00 2001 From: "Laura S. Mendoza" Date: Tue, 22 Oct 2019 14:34:13 +0200 Subject: [PATCH 06/10] [bf] return type of emissivity should always be 2D --- examples/tutorials/plot_custom_emissivity.py | 25 +++++++++++++------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/examples/tutorials/plot_custom_emissivity.py b/examples/tutorials/plot_custom_emissivity.py index b335339d6..0ac72309e 100644 --- a/examples/tutorials/plot_custom_emissivity.py +++ b/examples/tutorials/plot_custom_emissivity.py @@ -2,13 +2,14 @@ Computing a camera image with custom emissivity ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -This tutorial defines an emissivity that varies in space and computes the signal received by a camera using -this emissivity. +This tutorial defines an emissivity that varies in space and computes the signal +received by a camera using this emissivity. """ ############################################################################### # We start by loading a built-in `tofu` configuration and define a 2D camera. +import matplotlib.pyplot as plt import numpy as np import tofu as tf @@ -29,22 +30,25 @@ ############################################################################### # Now, we define an emissivity function that depends on r and z coordinates. # We can plot its profile in the (0, X, Z) plane. -import matplotlib.pyplot as plt - def emissivity(pts, t=None, vect=None): """Custom emissivity as a function of geometry. :param pts: ndarray of shape (3, n_points) (each column is a xyz coordinate) - :param t: optional, time parameter to add a time dependency to the emissivity function + :param t: optional, time parameter to add a time dependency to the + emissivity function :param vect: :return: - - emissivity - array holding the emissivity for each point in the input grid + - emissivity -- 2D array holding the emissivity for each point in the + input grid """ r, z = np.hypot(pts[0, :], pts[1, :]), pts[2, :] e = np.exp(-(r - 2.4) ** 2 / 0.2 ** 2 - z ** 2 / 0.4 ** 2) if t is not None: e = np.cos(np.atleast_1d(t))[:, None] * e[None, :] + else: + # as stated in documentation of calc_signal, e.ndim must be 2 + e = np.reshape(e, (1, -1)) return e @@ -56,10 +60,12 @@ def emissivity(pts, t=None, vect=None): emissivity_vals = emissivity(pts) emissivity_vals = emissivity_vals.reshape(X.shape) + def project_to_2D(xyz): """Projection to (0, X, Z) plane.""" return xyz[0], xyz[2] + fig, ax = plt.subplots() ax.pcolormesh(Y, Z, emissivity_vals) ax.set_xlabel('y') @@ -69,8 +75,9 @@ def project_to_2D(xyz): ax.legend(handles=[cam_center], labels=['camera pinhole'], loc='upper right') ############################################################################### -# Finally, we compute an image using the 2D camera and this emissivity. If we provide a time vector, the field -# will vary in a cosinusoidal fashion (see above definition) across time. +# Finally, we compute an image using the 2D camera and this emissivity. +# If we provide a time vector, the field will vary in a cosinusoidal fashion +# (see above definition) across time. time_vector = np.linspace(0, 2 * np.pi, num=100) @@ -78,4 +85,4 @@ def project_to_2D(xyz): resMode='rel', plot=False, t=time_vector) sig.plot(ntMax=1) -plt.show() \ No newline at end of file +plt.show() From 9e61eb966bd0648871945c2850ee77807bc5d01c Mon Sep 17 00:00:00 2001 From: VEZINET Didier Date: Wed, 6 Nov 2019 10:13:06 +0100 Subject: [PATCH 07/10] [Issue217] Corrected small bug in tofu/data/_plot.py --- examples/tutorials/plot_custom_emissivity.py | 2 +- tofu/data/_plot.py | 2 +- tofu/version.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/tutorials/plot_custom_emissivity.py b/examples/tutorials/plot_custom_emissivity.py index 0ac72309e..cdeb4cc72 100644 --- a/examples/tutorials/plot_custom_emissivity.py +++ b/examples/tutorials/plot_custom_emissivity.py @@ -83,6 +83,6 @@ def project_to_2D(xyz): sig, units = cam2d.calc_signal(emissivity, resMode='rel', plot=False, - t=time_vector) + t=None) sig.plot(ntMax=1) plt.show() diff --git a/tofu/data/_plot.py b/tofu/data/_plot.py index 67a885884..d99cb0abe 100644 --- a/tofu/data/_plot.py +++ b/tofu/data/_plot.py @@ -374,7 +374,7 @@ def _DataCam12D_plot(lData, key=None, nchMax=_nchMax, ntMax=_ntMax, lt = [dd.t for dd in lData] nt = lData[0].nt if nt == 1: - Dt = [t[0]-0.001,t[0]+0.001] + Dt = [lt[0][0]-0.001, lt[0][0]+0.001] else: Dt = np.array([[np.nanmin(t), np.nanmax(t)] for t in lt]) Dt = [np.min(Dt[:,0]), np.max(Dt[:,1])] diff --git a/tofu/version.py b/tofu/version.py index 3a178e146..51f9e83c0 100644 --- a/tofu/version.py +++ b/tofu/version.py @@ -1,2 +1,2 @@ # Do not edit, pipeline versioning governed by git tags! -__version__ = '1.4.1-190-gd25622d' +__version__ = '1.4.1-214-g7409274' From 8074dbc7c68fdb3033dc91a9b9849fdb25a129f4 Mon Sep 17 00:00:00 2001 From: VEZINET Didier Date: Wed, 6 Nov 2019 11:04:46 +0100 Subject: [PATCH 08/10] [Issue217] plot with t=None now operational, was due to np.squeeze on (1, npix) data and np.squeeze on t=[0], de-activated np.squeeze --- tofu/utils.py | 32 ++++++++++++++++++++------------ tofu/version.py | 2 +- 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/tofu/utils.py b/tofu/utils.py index 38a54167a..f727a83ca 100644 --- a/tofu/utils.py +++ b/tofu/utils.py @@ -546,7 +546,7 @@ def _get_load_npzmat_dict(out, pfe, mode='npz', exclude_keys=[]): if out[k].ndim == 1: dout[k] = out[k].tolist() else: - dout[k] = np.squeeze(out[k],axis=0).tolist() + dout[k] = np.atleast_1d(np.squeeze(out[k],axis=0)).tolist() if type(dout[k][0]) is str: dout[k] = [kk.strip() for kk in dout[k]] else: @@ -555,7 +555,7 @@ def _get_load_npzmat_dict(out, pfe, mode='npz', exclude_keys=[]): dout[k] = tuple(dout[k]) elif typ=='ndarray': if mode == 'mat': - dout[k] = np.squeeze(out[k]) + dout[k] = np.atleast_1d(np.squeeze(out[k])) if dout[k].shape == (0,0): dout[k] = dout[k].ravel() else: @@ -2484,11 +2484,15 @@ def func(li, val=val, n1=n1, n2=n2): else: assert type(val) is np.ndarray - val = val.squeeze() + # val = np.atleast_1d(val.squeeze()) ndim = val.ndim - assert ndim >= len(lrids) - assert len(lrids) >= ninds - assert ndim >= ninds + c0 = ndim >= len(lrids) and len(lrids) >= ninds and ndim >= ninds + if not c0: + msg = "Wrong dimension / shape / references!\n" + msg += " val.ndim : {}\n".format(ndim) + msg += " lrids : {}\n".format(str(lrids)) + msg += " len(linds): {}\n".format(ninds) + raise Exception(msg) if ndim == ninds: if ndim == 1: @@ -2566,13 +2570,17 @@ def func(val, ind0=None, refb=refb): return np.nanargmin(np.abs(ref-val[1])) else: - refb = 0.5*(ref[1:]+ref[:-1]) - if Type == 'x': - def func(val, ind0=None, refb=refb): - return np.digitize([val[0]], refb)[0] + if ref.size == 1: + def func(val, ind0=None): + return 0 else: - def func(val, ind0=None, refb=refb): - return np.digitize([val[1]], refb)[0] + refb = 0.5*(ref[1:]+ref[:-1]) + if Type == 'x': + def func(val, ind0=None, refb=refb): + return np.digitize([val[0]], refb)[0] + else: + def func(val, ind0=None, refb=refb): + return np.digitize([val[1]], refb)[0] elif indother is None: assert ref.ndim == 2 if np.any(np.isnan(ref)): diff --git a/tofu/version.py b/tofu/version.py index 51f9e83c0..272db561d 100644 --- a/tofu/version.py +++ b/tofu/version.py @@ -1,2 +1,2 @@ # Do not edit, pipeline versioning governed by git tags! -__version__ = '1.4.1-214-g7409274' +__version__ = '1.4.1-215-g9e61eb9' From 754c8bb1c9a0b6f06b534ee57953d4ec9d260d60 Mon Sep 17 00:00:00 2001 From: VEZINET Didier Date: Wed, 6 Nov 2019 11:42:23 +0100 Subject: [PATCH 09/10] [Issue217] Bug found in _GG.LOS_calc_signal: examples/tutorials/plot_custom_emissivity.py gives very different results depending on whether newcalc=True or False. False definitely seems to be the proper solution --- examples/tutorials/plot_custom_emissivity.py | 9 ++++++--- tofu/version.py | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/examples/tutorials/plot_custom_emissivity.py b/examples/tutorials/plot_custom_emissivity.py index cdeb4cc72..7cb00b855 100644 --- a/examples/tutorials/plot_custom_emissivity.py +++ b/examples/tutorials/plot_custom_emissivity.py @@ -21,7 +21,7 @@ N12=100, F=0.1, D12=0.1, - angs=[np.pi, 0, 0], + angs=[np.pi, np.pi/6, 0], Name="", Exp="", Diag="", @@ -82,7 +82,10 @@ def project_to_2D(xyz): time_vector = np.linspace(0, 2 * np.pi, num=100) sig, units = cam2d.calc_signal(emissivity, - resMode='rel', plot=False, - t=None) + res=0.01, + reflections=False, + newcalc=False, + plot=False, + t=time_vector) sig.plot(ntMax=1) plt.show() diff --git a/tofu/version.py b/tofu/version.py index 272db561d..41b520da4 100644 --- a/tofu/version.py +++ b/tofu/version.py @@ -1,2 +1,2 @@ # Do not edit, pipeline versioning governed by git tags! -__version__ = '1.4.1-215-g9e61eb9' +__version__ = '1.4.1-216-g8074dbc' From 694f462b08bf1849e5e26788080c2a10e61f19a3 Mon Sep 17 00:00:00 2001 From: VEZINET Didier Date: Wed, 6 Nov 2019 12:03:59 +0100 Subject: [PATCH 10/10] [Issue217] Trying nexcalc=True/False --- examples/tutorials/plot_custom_emissivity.py | 2 +- tofu/version.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/tutorials/plot_custom_emissivity.py b/examples/tutorials/plot_custom_emissivity.py index 7cb00b855..349aa3d45 100644 --- a/examples/tutorials/plot_custom_emissivity.py +++ b/examples/tutorials/plot_custom_emissivity.py @@ -84,7 +84,7 @@ def project_to_2D(xyz): sig, units = cam2d.calc_signal(emissivity, res=0.01, reflections=False, - newcalc=False, + newcalc=True, plot=False, t=time_vector) sig.plot(ntMax=1) diff --git a/tofu/version.py b/tofu/version.py index 41b520da4..1fc557b2f 100644 --- a/tofu/version.py +++ b/tofu/version.py @@ -1,2 +1,2 @@ # Do not edit, pipeline versioning governed by git tags! -__version__ = '1.4.1-216-g8074dbc' +__version__ = '1.4.1-217-g754c8bb'