From cab156c413c487b8eab59cf9a6d1608bcb2c540b Mon Sep 17 00:00:00 2001 From: VEZINET Didier Date: Wed, 20 Nov 2019 13:36:50 +0100 Subject: [PATCH 1/4] [Issue264] Introduced unique configs and a correspondence table for shortcuts in tofu/geom/utils.py, retro-compatibility should work --- tofu/geom/utils.py | 114 +++++++++++++++++++++++++++++---------------- tofu/version.py | 2 +- 2 files changed, 75 insertions(+), 41 deletions(-) diff --git a/tofu/geom/utils.py b/tofu/geom/utils.py index 063c3a9ee..2c8e33f3f 100644 --- a/tofu/geom/utils.py +++ b/tofu/geom/utils.py @@ -619,51 +619,85 @@ def _compute_CamLOS2D_pinhole(P=None, F=0.1, D12=0.1, N12=100, _ExpWest = 'WEST' _ExpITER = 'ITER' -_dconfig = {'A1': {'Exp': _ExpWest, - 'Ves': ['V1']}, - 'A2': {'Exp': _ExpITER, - 'Ves': ['V0']}, - 'A3': {'Exp': _ExpWest, - 'PlasmaDomain': ['Sep']}, - 'B1': {'Exp': _ExpWest, - 'Ves': ['V2'], - 'PFC': ['BaffleV0', 'DivUpV1', 'DivLowITERV1']}, - 'B2': {'Exp': _ExpWest, - 'Ves': ['V2'], - 'PFC': ['BaffleV1', 'DivUpV2', 'DivLowITERV2', - 'BumperInnerV1', 'BumperOuterV1', - 'IC1V1', 'IC2V1', 'IC3V1']}, - 'B3': {'Exp': _ExpWest, - 'Ves': ['V2'], - 'PFC': ['BaffleV2', 'DivUpV3', 'DivLowITERV3', - 'BumperInnerV3', 'BumperOuterV3', - 'IC1V1', 'IC2V1', 'IC3V1', - 'LH1V1', 'LH2V1', - 'RippleV1', 'VDEV0']}, - 'B4': {'Exp': _ExpITER, - 'Ves': ['V1'], - 'PFC': ['BLK01', 'BLK02', 'BLK03', 'BLK04', 'BLK05', 'BLK06', - 'BLK07', 'BLK08', 'BLK09', 'BLK10', 'BLK11', 'BLK12', - 'BLK13', 'BLK14', 'BLK15', 'BLK16', 'BLK17', 'BLK18', - 'Div1', 'Div2', 'Div3', 'Div4', 'Div5', 'Div6']} +# Dictionnary of unique config names +_DCONFIG = {'WEST-V1': {'Exp': _ExpWest, + 'Ves': ['V1']}, + 'ITER-V1': {'Exp': _ExpITER, + 'Ves': ['V0']}, + 'WEST-Sep': {'Exp': _ExpWest, + 'PlasmaDomain': ['Sep']}, + 'WEST-V2': {'Exp': _ExpWest, + 'Ves': ['V2'], + 'PFC': ['BaffleV0', 'DivUpV1', 'DivLowITERV1']}, + 'WEST-V3': {'Exp': _ExpWest, + 'Ves': ['V2'], + 'PFC': ['BaffleV1', 'DivUpV2', 'DivLowITERV2', + 'BumperInnerV1', 'BumperOuterV1', + 'IC1V1', 'IC2V1', 'IC3V1']}, + 'WEST-V4': {'Exp': _ExpWest, + 'Ves': ['V2'], + 'PFC': ['BaffleV2', 'DivUpV3', 'DivLowITERV3', + 'BumperInnerV3', 'BumperOuterV3', + 'IC1V1', 'IC2V1', 'IC3V1', + 'LH1V1', 'LH2V1', + 'RippleV1', 'VDEV0']}, + 'ITER-V2': {'Exp': _ExpITER, + 'Ves': ['V1'], + 'PFC': ['BLK01', 'BLK02', 'BLK03', 'BLK04', 'BLK05', 'BLK06', + 'BLK07', 'BLK08', 'BLK09', 'BLK10', 'BLK11', 'BLK12', + 'BLK13', 'BLK14', 'BLK15', 'BLK16', 'BLK17', 'BLK18', + 'Div1', 'Div2', 'Div3', 'Div4', 'Div5', 'Div6']} } -def _create_config_testcase(config='A1', out='object', - path=_path_testcases, dconfig=_dconfig): +# Each config can be called by various names (for benchmark and +# retro-compatibility), this table stores the available names for each unique +# config in _DCONFIG +_DCONFIG_TABLE = {'ITER': 'ITER-V2', + 'WEST': 'WEST-V4', + 'A1': 'WEST-V1', + 'A2': 'ITER-V1', + 'A3': 'WEST-Sep', + 'B1': 'WEST-V2', + 'B2': 'WEST-V3', + 'B3': 'WEST-V4', + 'B4': 'ITER-V2'} + +# Default config +_DEFCONFIG = 'ITER' + + +def _create_config_testcase(config=None, returnas='object', + path=_path_testcases, dconfig=_DCONFIG, + dconfig_table=_DCONFIG_TABLE): """ Load the desired test case configuration Choose from one of the reference preset configurations: {0} """.format('['+', '.join(dconfig.keys())+']') - assert all([type(ss) is str for ss in [config,path]]) + # Check input + if config is None: + config = _DEFCONFIG + assert all([type(ss) is str for ss in [config, path]]) assert type(dconfig) is dict - if not config in dconfig.keys(): - msg = "Please a valid config, from one of the following:\n" - msg += "["+", ".join(dconfig.keys())+"+]" - raise Exception(msg) path = os.path.abspath(path) + # Check config is available + if config in dconfig.keys(): + pass + + elif config in dconfig_table.keys(): + # Get corresponding config + config = dconfig_table[config] + + else: + msg = ("The provided config name is not valid:\n" + + "Please choose among either:\n" + + "\t - unique keys: {}\n".format(list(dconfig.keys())) + + "\t - shortcuts : {}\n\n".format(list(dconfig_table.keys())) + + " => you provided: case = {}\n".format(config)) + raise Exception(msg) + # Get file names for config lf = [f for f in os.listdir(path) if f[-4:]=='.txt'] lS = [] @@ -682,11 +716,11 @@ def _create_config_testcase(config='A1', out='object', pfe = os.path.join(path,ff[0]) obj = eval('_core.'+cc).from_txt(pfe, Name=ss, Type='Tor', Exp=dconfig[config]['Exp'], - out=out) - if out not in ['object',object]: + out=returnas) + if returnas not in ['object',object]: obj = ((ss,{'Poly':obj[0], 'pos':obj[1], 'extent':obj[2]}),) lS.append(obj) - if out == 'dict': + if returnas == 'dict': conf = dict([tt for tt in lS]) else: conf = _core.Config(Name=config, Exp=dconfig[config]['Exp'], lStruct=lS) @@ -696,7 +730,7 @@ def create_config(case=None, Exp='Dummy', Type='Tor', Lim=None, Bump_posextent=[np.pi/4., np.pi/4], R=2.4, r=1., elong=0., Dshape=0., divlow=True, divup=True, nP=200, - out='object', SavePath='./', path=_path_testcases): + returnas='object', SavePath='./', path=_path_testcases): """ Create easily a tofu.geom.Config object In tofu, a Config (short for geometrical configuration) refers to the 3D @@ -751,12 +785,12 @@ def create_config(case=None, Exp='Dummy', Type='Tor', """ if case is not None: - conf = _create_config_testcase(config=case, out=out, path=path) + conf = _create_config_testcase(config=case, returnas=returnas, path=path) else: poly, pbump, pbaffle = _compute_VesPoly(R=R, r=r, elong=elong, Dshape=Dshape, divlow=divlow, divup=divup, nP=nP) - if out=='dict': + if returnas == 'dict': conf = {'Ves':{'Poly':poly}, 'Baffle':{'Poly':pbaffle}, 'Bumper':{'Poly':pbump, diff --git a/tofu/version.py b/tofu/version.py index 1bd359aa2..e8515769a 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-303-gf837259' +__version__ = '1.4.1-312-g2cc236b' From e9dc53d05623fcb89d00131c1bfeaeb9985642c1 Mon Sep 17 00:00:00 2001 From: VEZINET Didier Date: Wed, 20 Nov 2019 14:01:51 +0100 Subject: [PATCH 2/4] [Issue264] Made sure default config is used when no argument is passed --- tofu/geom/utils.py | 58 +++++++++++++++++++++++++++++++++++++--------- tofu/version.py | 2 +- 2 files changed, 48 insertions(+), 12 deletions(-) diff --git a/tofu/geom/utils.py b/tofu/geom/utils.py index 2c8e33f3f..12219739b 100644 --- a/tofu/geom/utils.py +++ b/tofu/geom/utils.py @@ -236,8 +236,8 @@ def compute_RaysCones(Ds, us, angs=np.pi/90., nP=40): ########################################################### -def _compute_VesPoly(R=2.4, r=1., elong=0., Dshape=0., - divlow=True, divup=True, nP=200): +def _compute_VesPoly(R=None, r=None, elong=None, Dshape=None, + divlow=None, divup=None, nP=None): """ Utility to compute three 2D (R,Z) polygons One represents a vacuum vessel, one an outer bumper, one a baffle @@ -252,20 +252,27 @@ def _compute_VesPoly(R=2.4, r=1., elong=0., Dshape=0., Parameters ---------- - R: int / float + R: None / int / float Major radius used as a center of the vessel - r : int / float + If None, defaults to 2.4 + r : None / int / float Minor radius of the vessel - elong: int / float + If None, defaults to 1. + elong: None / int / float Dimensionless elongation parameter in [-1;1] - Dshape: int / float + If None, defaults to 0. + Dshape: None / int / float Dimensionless parameter for the D-shape (in-out asymmetry) in [0;1] - divlow: bool + If None, defaults to 0. + divlow: None / bool Flag indicating whether to incude a lower divertor-like shape - divup: bool + If None, defaults to True + divup: None / bool Flag indicating whether to incude an upper divertor-like shape - nP : int + If None, defaults to True + nP : None / int Parameter specifying approximately the number of points of the vessel + If None, defaults to 200 Return ------ @@ -277,6 +284,22 @@ def _compute_VesPoly(R=2.4, r=1., elong=0., Dshape=0., Closed (2,N) polygon defining the lower baffle """ + # Check inputs + if R is None: + R = 2.4 + if r is None: + r = 1. + if elong is None: + elong = 0. + if Dshape is None: + Dshape = 0. + if divlow is None: + divlow = True + if divup is None: + divup = True + if nP is None: + nP = 200 + # Basics (center, theta, unit vectors) cent = np.r_[R,0.] theta = np.linspace(-np.pi,np.pi,nP) @@ -728,8 +751,8 @@ def _create_config_testcase(config=None, returnas='object', def create_config(case=None, Exp='Dummy', Type='Tor', Lim=None, Bump_posextent=[np.pi/4., np.pi/4], - R=2.4, r=1., elong=0., Dshape=0., - divlow=True, divup=True, nP=200, + R=None, r=None, elong=None, Dshape=None, + divlow=None, divup=None, nP=None, returnas='object', SavePath='./', path=_path_testcases): """ Create easily a tofu.geom.Config object @@ -784,6 +807,19 @@ def create_config(case=None, Exp='Dummy', Type='Tor', - a dictionary of the polygons and their pos/extent (if any) """ + lp = [R, r, elong, Dshape, divlow, divup, nP] + lpstr = '[R, r, elong, Dshape, divlow, divup, nP]' + lc = [case is not None, + any([pp is not None for pp in lp])] + if np.sum(lc) > 1: + msg = ("Please provide either:\n" + + "\t- case: the name of a stored case\n" + + "\t- geometrical parameters {}".format(lpstr)) + raise Exception(msg) + elif not any(lc): + case = _DEFCONFIG + + # Get config, either from known case or geometrical parameterization if case is not None: conf = _create_config_testcase(config=case, returnas=returnas, path=path) else: diff --git a/tofu/version.py b/tofu/version.py index e8515769a..3ab9be99b 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-312-g2cc236b' +__version__ = '1.4.1-313-gcab156c' From c5065a70be9cd350f33ebc31e6b68bee72fad1d0 Mon Sep 17 00:00:00 2001 From: VEZINET Didier Date: Wed, 20 Nov 2019 14:09:41 +0100 Subject: [PATCH 3/4] [Issue264] PEP8 Compliance --- tofu/geom/utils.py | 16 ++++++++++------ tofu/version.py | 2 +- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/tofu/geom/utils.py b/tofu/geom/utils.py index 12219739b..4d807339c 100644 --- a/tofu/geom/utils.py +++ b/tofu/geom/utils.py @@ -666,9 +666,10 @@ def _compute_CamLOS2D_pinhole(P=None, F=0.1, D12=0.1, N12=100, 'RippleV1', 'VDEV0']}, 'ITER-V2': {'Exp': _ExpITER, 'Ves': ['V1'], - 'PFC': ['BLK01', 'BLK02', 'BLK03', 'BLK04', 'BLK05', 'BLK06', - 'BLK07', 'BLK08', 'BLK09', 'BLK10', 'BLK11', 'BLK12', - 'BLK13', 'BLK14', 'BLK15', 'BLK16', 'BLK17', 'BLK18', + 'PFC': ['BLK01', 'BLK02', 'BLK03', 'BLK04', 'BLK05', + 'BLK06', 'BLK07', 'BLK08', 'BLK09', 'BLK10', + 'BLK11', 'BLK12', 'BLK13', 'BLK14', 'BLK15', + 'BLK16', 'BLK17', 'BLK18', 'Div1', 'Div2', 'Div3', 'Div4', 'Div5', 'Div6']} } @@ -821,10 +822,13 @@ def create_config(case=None, Exp='Dummy', Type='Tor', # Get config, either from known case or geometrical parameterization if case is not None: - conf = _create_config_testcase(config=case, returnas=returnas, path=path) + conf = _create_config_testcase(config=case, + returnas=returnas, path=path) else: - poly, pbump, pbaffle = _compute_VesPoly(R=R, r=r, elong=elong, Dshape=Dshape, - divlow=divlow, divup=divup, nP=nP) + poly, pbump, pbaffle = _compute_VesPoly(R=R, r=r, + elong=elong, Dshape=Dshape, + divlow=divlow, divup=divup, + nP=nP) if returnas == 'dict': conf = {'Ves':{'Poly':poly}, diff --git a/tofu/version.py b/tofu/version.py index 3ab9be99b..999b0a352 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-313-gcab156c' +__version__ = '1.4.1-314-ge9dc53d' From 277a1358ee72a046653a227fcb9887013a9aa8ef Mon Sep 17 00:00:00 2001 From: VEZINET Didier Date: Wed, 20 Nov 2019 14:10:52 +0100 Subject: [PATCH 4/4] [Issue264] PEP8 Compliance 2 --- tofu/geom/utils.py | 5 +++-- tofu/version.py | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/tofu/geom/utils.py b/tofu/geom/utils.py index 4d807339c..943f9485f 100644 --- a/tofu/geom/utils.py +++ b/tofu/geom/utils.py @@ -670,7 +670,8 @@ def _compute_CamLOS2D_pinhole(P=None, F=0.1, D12=0.1, N12=100, 'BLK06', 'BLK07', 'BLK08', 'BLK09', 'BLK10', 'BLK11', 'BLK12', 'BLK13', 'BLK14', 'BLK15', 'BLK16', 'BLK17', 'BLK18', - 'Div1', 'Div2', 'Div3', 'Div4', 'Div5', 'Div6']} + 'Div1', 'Div2', 'Div3', + 'Div4', 'Div5', 'Div6']} } # Each config can be called by various names (for benchmark and @@ -741,7 +742,7 @@ def _create_config_testcase(config=None, returnas='object', obj = eval('_core.'+cc).from_txt(pfe, Name=ss, Type='Tor', Exp=dconfig[config]['Exp'], out=returnas) - if returnas not in ['object',object]: + if returnas not in ['object', object]: obj = ((ss,{'Poly':obj[0], 'pos':obj[1], 'extent':obj[2]}),) lS.append(obj) if returnas == 'dict': diff --git a/tofu/version.py b/tofu/version.py index 999b0a352..c0aed3f84 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-314-ge9dc53d' +__version__ = '1.4.1-315-gc5065a7'