From 784f940f88d18ffed97a0656a11ca64657063bdd Mon Sep 17 00:00:00 2001 From: dvezinet Date: Tue, 10 Oct 2023 00:50:41 +0200 Subject: [PATCH] [#863] compute_diagnostic_signal(method='vos') implemented for broadband --- tofu/data/_class8_compute_signal.py | 202 ++++++++++++++++++++- tofu/tests/tests09_tutorials/tuto_real0.py | 51 ++++-- 2 files changed, 234 insertions(+), 19 deletions(-) diff --git a/tofu/data/_class8_compute_signal.py b/tofu/data/_class8_compute_signal.py index 3afb34bb8..54838cb7a 100644 --- a/tofu/data/_class8_compute_signal.py +++ b/tofu/data/_class8_compute_signal.py @@ -1,6 +1,7 @@ import datetime as dtm +import itertools as itt import numpy as np @@ -122,15 +123,16 @@ def compute_signal( # compute # -------------- + # pick routine if method == 'los': func = _compute_los else: if spectro is True: func = _compute_vos_spectro else: - msg = "vos for non-spectro not implemented yet" - raise NotImplementedError(msg) + func = _compute_vos_broadband + # call routine dout, dt = func( coll=coll, is2d=is2d, @@ -928,8 +930,16 @@ def _units_integration( key_bs=None, ): + # ----------------- + # integrand + + # units0 units0 = coll.ddata[key_integrand]['units'] + # -------------- + # los dimension + + # units_bs wbs = coll._which_bsplines kap = coll.dobj[wbs][key_bs]['apex'] lunits = list({coll.ddata[k0]['units'] for k0 in kap}) @@ -939,6 +949,7 @@ def _units_integration( msg = "Don't know how to interpret line-integration units from bspline" raise Exception(msg) + # units_bs from subbs if relevant wm = coll._which_mesh keym = coll.dobj[wbs][key_bs][wm] subbs = coll.dobj[wm][keym]['subbs'] @@ -956,7 +967,192 @@ def _units_integration( # ################################################################## # ################################################################## -# VOS +# VOS - Broadband +# ################################################################## + + +def _compute_vos_broadband( + coll=None, + is2d=None, + PHA=None, + key=None, + key_diag=None, + key_cam=None, + key_bs=None, + res=None, + mode=None, + key_integrand=None, + key_ref_spectro=None, + key_bs_spectro=None, + key_ref_cos=None, + groupby=None, + val_init=None, + ref_com=None, + brightness=None, + spectral_binning=None, + # dvos + dvos=None, + # verb + verb=None, + # unused + **kwdargs, +): + + # ------------------------ + # check uniformity of dvos + + dt = None + # check all keym and res_RZ are similar + lkm = list(set([v0['keym'] for v0 in dvos.values()])) + lres = list(set([tuple(v0['res_RZ']) for v0 in dvos.values()])) + + if len(lkm) != 1: + lstr = [f"\t- '{k0}': '{v0['keym']}'" for k0, v0 in dvos.items()] + msg = ( + "All cameras vos were not sampled using the same mesh!\n" + + "\n".join(lstr) + ) + raise Exception(msg) + + if len(lres) != 1: + lstr = [f"\t- '{k0}': '{v0['res_RZ']}'" for k0, v0 in dvos.items()] + msg = ( + "All cameras vos were not sampled using the same resolution!\n" + + "\n".join(lstr) + ) + raise Exception(msg) + + # extract + keym = lkm[0] + res_RZ = list(lres[0]) + + # ----------------- + # get mesh sampling + + # get dsamp + dsamp = coll.get_sample_mesh( + key=keym, + res=res_RZ, + mode='abs', + grid=False, + in_mesh=True, + # non-used + x0=None, + x1=None, + Dx0=None, + Dx1=None, + imshow=False, + store=False, + kx0=None, + kx1=None, + ) + + x0u = dsamp['x0']['data'] + x1u = dsamp['x1']['data'] + + # -------------- + # prepare + + wbs = coll._which_bsplines + + # units + units0 = coll.ddata[key_integrand]['units'] + + # ----------------------------- + # loop on cameras + + dout = {k0: {} for k0 in dvos.keys()} + for k0, v0 in dvos.items(): + + # group + units_vos = v0['sang']['units'] + + # -------------- + # loop on pixels + + shape = None + shape_cam = v0['indr']['data'].shape[:-1] + assert shape_cam == coll.dobj['camera'][k0]['dgeom']['shape'] + ref_cam = coll.dobj['camera'][k0]['dgeom']['ref'] + for ind in np.ndindex(shape_cam): + + # no valid los in group + iok = v0['indr']['data'][ind] >= 0 + if not np.any(iok): + continue + + # vos re-creation + ind_RZ = tuple(list(ind) + [iok]) + R = x0u[v0['indr']['data'][ind_RZ]] + Z = x1u[v0['indz']['data'][ind_RZ]] + + # ----------------------------- + # interpolate on matching wavelength ? + + douti = coll.interpolate( + keys=key_integrand, + ref_key=key_bs, + x0=R, + x1=Z, + grid=False, + submesh=True, + ref_com=ref_com, + domain=None, + # azone=None, + details=False, + crop=None, + nan0=False, + val_out=0., + return_params=False, + store=False, + )[key_integrand] + + # extracti shape and ref from integrand + datai, refi = douti['data'], douti['ref'] + if shape is None: + axis = refi.index(None) + shape = list(datai.shape) + shape = tuple( + np.r_[shape[:axis], shape_cam, shape[axis+1:]].astype(int) + ) + ref = tuple(np.r_[refi[:axis], ref_cam, refi[axis+1:]]) + data = np.full(shape, val_init) + ind_data = [[slice(None)] for ii in range(datai.ndim)] + ind_sa = [[None] for ii in range(datai.ndim)] + + # ------------ + # integrate + + ind_data[axis] = ind + ind_sa[axis] = ind_RZ + data[tuple(itt.chain.from_iterable(ind_data))] = np.nansum( + datai + * v0['sang']['data'][tuple(itt.chain.from_iterable(ind_sa))], + axis=axis, + ) + + # -------------- + # post-treatment + + unitsi = units0 * units_vos + + # fill dout + dout[k0] = { + 'key': f'{key}_{k0}', + 'data': data, + 'ref': ref, + 'units': unitsi, + } + + # ---------- + # clean up + + return dout, dt + + +# ################################################################## +# ################################################################## +# VOS - spectro # ################################################################## diff --git a/tofu/tests/tests09_tutorials/tuto_real0.py b/tofu/tests/tests09_tutorials/tuto_real0.py index 72a69546f..f78d6d3e7 100644 --- a/tofu/tests/tests09_tutorials/tuto_real0.py +++ b/tofu/tests/tests09_tutorials/tuto_real0.py @@ -36,19 +36,19 @@ def main(): # add several diagnostics # add broadband - _add_broadband(coll, conf, vos=True) + _add_broadband(coll, key_diag='d0', conf=conf, vos=True) # add collimator - _add_collimator(coll, conf, vos=True) + # _add_collimator(coll, conf, vos=True) # add 2d camera - _add_2d(coll, conf) + _add_2d(coll, key_diag='c2d', conf=conf, vos=True) # add PHA # _add_PHA(coll, conf) # add spectrometer - _add_spectrometer(coll, conf, vos=True) # , crystals=['c0']) + # _add_spectrometer(coll, conf, vos=True) # , crystals=['c0']) # add spectro-like without crystal # _add_spectrometer_like(coll, config=conf, key_diag='d02') @@ -58,7 +58,8 @@ def main(): _compute_synth_signal( coll, - ldiag=['d01'], + ldiag=['d0', 'c2d'], + method='vos', spectral_binning=True, ) @@ -219,6 +220,7 @@ def _create_plasma(): def _add_broadband( coll=None, + key_diag=None, conf=None, vos=None, ): @@ -229,7 +231,7 @@ def _add_broadband( # coll.add_camera_pinhole( # key='bb0', # key_pinhole=None, - # key_diag='d0', + # key_diag=key_diag, # cam_type='1d', # R=3.3, # z=-0.6, @@ -242,7 +244,7 @@ def _add_broadband( # pix_size=3e-3, # pix_spacing=5e-3, # pinhole_radius=None, - # pinhole_size=[1e-3, 1e-3], + # pinhole_size=[2e-3, 1e-3], # reflections_nb=0, # reflections_type=None, # compute=False, @@ -252,7 +254,7 @@ def _add_broadband( coll.add_camera_pinhole( key='bb1', key_pinhole=None, - key_diag='d0', + key_diag=key_diag, cam_type='1d', R=3.3, z=0.6, @@ -265,7 +267,7 @@ def _add_broadband( pix_size=3e-3, pix_spacing=5e-3, pinhole_radius=None, - pinhole_size=[1e-3, 1e-3], + pinhole_size=[3e-3, 2e-3], reflections_nb=0, reflections_type=None, compute=True, @@ -274,9 +276,9 @@ def _add_broadband( if vos is True: coll.compute_diagnostic_vos( - 'd0', + key_diag=key_diag, key_mesh='m0', - res_RZ=0.01, + res_RZ=0.005, res_phi=0.01, visibility=False, store=True, @@ -347,15 +349,17 @@ def _add_collimator( def _add_2d( coll=None, + key_diag=None, conf=None, + vos=None, ): # --------------------- # add 2 pinhole cameras coll.add_camera_pinhole( - key='c2d', - key_diag='d1', + key=key_diag, + key_diag=key_diag, key_pinhole=None, cam_type='2d', R=3.3, @@ -376,6 +380,16 @@ def _add_2d( config=conf, ) + if vos is True: + coll.compute_diagnostic_vos( + key_diag, + key_mesh='m0', + res_RZ=0.02, + res_phi=0.02, + visibility=False, + store=True, + ) + def _add_PHA( coll=None, @@ -769,7 +783,12 @@ def _nine0e1_from_orientations( # ##################################################### -def _compute_synth_signal(coll=None, ldiag=None, spectral_binning=None): +def _compute_synth_signal( + coll=None, + ldiag=None, + method=None, + spectral_binning=None, +): # ------------- # list of diags @@ -786,7 +805,7 @@ def _compute_synth_signal(coll=None, ldiag=None, spectral_binning=None): continue # params - if k0 == 'd0': + if k0 in ['d0', 'c2d']: key_integrand = 'emiss1d' ref_com = 'nt' # elif k0 == 'diag00': @@ -802,7 +821,7 @@ def _compute_synth_signal(coll=None, ldiag=None, spectral_binning=None): key_diag=k0, key_cam=None, key_integrand=key_integrand, - method='vos', + method=method, res=0.001, mode='abs', groupby=None,