Skip to content

Commit 8cd1fab

Browse files
committed
pymcnp/inp: refactored InpBuilder
1 parent a203282 commit 8cd1fab

File tree

533 files changed

+27199
-1020
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

533 files changed

+27199
-1020
lines changed

scripts/inp_code.py

+150-5
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,53 @@ def _REGEX(element):
6060
return o
6161

6262

63+
def ATTRS_DATACLASS(element, t):
64+
a = []
65+
b = []
66+
67+
for attribute in element.attributes:
68+
if attribute.optional:
69+
if attribute.type.startswith('types.Tuple'):
70+
if 'types.Integer' in attribute.type:
71+
b += [
72+
f'{attribute.name}: list[str] | list[int] | list[{attribute.type[12:-1]}] = None'
73+
]
74+
elif 'types.Real' in attribute.type:
75+
b += [
76+
f'{attribute.name}: list[str] | list[float] | list[{attribute.type[12:-1]}] = None'
77+
]
78+
else:
79+
b += [f'{attribute.name}: list[str] | list[{attribute.type[12:-1]}] = None']
80+
else:
81+
if 'types.Integer' in attribute.type:
82+
b += [f'{attribute.name}: str | int | {attribute.type} = None']
83+
elif 'types.Real' in attribute.type:
84+
b += [f'{attribute.name}: str | float | {attribute.type} = None']
85+
else:
86+
b += [f'{attribute.name}: str | {attribute.type} = None']
87+
else:
88+
if attribute.type.startswith('types.Tuple'):
89+
if 'types.Integer' in attribute.type:
90+
a += [
91+
f'{attribute.name}: list[str] | list[int] | list[{attribute.type[12:-1]}]'
92+
]
93+
elif 'types.Real' in attribute.type:
94+
a += [
95+
f'{attribute.name}: list[str] | list[float] | list[{attribute.type[12:-1]}]'
96+
]
97+
else:
98+
a += [f'{attribute.name}: list[str] | list[{attribute.type[12:-1]}]']
99+
else:
100+
if 'types.Integer' in attribute.type:
101+
a += [f'{attribute.name}: str | int | {attribute.type}']
102+
elif 'types.Real' in attribute.type:
103+
a += [f'{attribute.name}: str | float | {attribute.type}']
104+
else:
105+
a += [f'{attribute.name}: str | {attribute.type}']
106+
107+
return f'\n{TABS(t)}'.join(a + b).strip()
108+
109+
63110
def ATTRS_DICT(element):
64111
a = ''
65112
b = ''
@@ -129,17 +176,88 @@ def ATTRS_COMMENT(element, t):
129176
return o.strip()
130177

131178

179+
def ATTRS_BUILDER(element, t):
180+
o = ''
181+
182+
for attribute in element.attributes:
183+
if attribute.type.startswith('types.Tuple'):
184+
o += f'{TABS(t)}{attribute.name} = []\n'
185+
o += f'{TABS(t)}for item in self.{attribute.name}:\n'
186+
187+
if 'types.Integer' in attribute.type:
188+
o += f'{TABS(t)} if isinstance(item, {attribute.type[12:-1]}):\n'
189+
o += f'{TABS(t)} {attribute.name}.append(item)\n'
190+
o += f'{TABS(t)} elif isinstance(item, int):\n'
191+
o += f'{TABS(t)} {attribute.name}.append({attribute.type[12:-1]}(item))\n'
192+
o += f'{TABS(t)} elif isinstance(item, str):\n'
193+
o += f'{TABS(t)} {attribute.name}.append({attribute.type[12:-1]}.from_mcnp(item))\n'
194+
elif 'types.Real' in attribute.type:
195+
o += f'{TABS(t)} if isinstance(item, {attribute.type[12:-1]}):\n'
196+
o += f'{TABS(t)} {attribute.name}.append(item)\n'
197+
o += f'{TABS(t)} elif isinstance(item, float) or isinstance(item, int):\n'
198+
o += f'{TABS(t)} {attribute.name}.append({attribute.type[12:-1]}(item))\n'
199+
o += f'{TABS(t)} elif isinstance(item, str):\n'
200+
o += f'{TABS(t)} {attribute.name}.append({attribute.type[12:-1]}.from_mcnp(item))\n'
201+
else:
202+
o += f'{TABS(t)} if isinstance(item, {attribute.type[12:-1]}):\n'
203+
o += f'{TABS(t)} {attribute.name}.append(item)\n'
204+
o += f'{TABS(t)} elif isinstance(item, str):\n'
205+
o += f'{TABS(t)} {attribute.name}.append({attribute.type[12:-1]}.from_mcnp(item))\n'
206+
o += f'{TABS(t)} else:\n'
207+
o += f'{TABS(t)} {attribute.name}.append(item.build())\n'
208+
209+
o += f'{TABS(t)}{attribute.name} = types.Tuple({attribute.name})\n'
210+
else:
211+
if attribute.optional:
212+
o += f'{TABS(t)}{attribute.name} = None\n'
213+
214+
if 'types.Integer' in attribute.type:
215+
o += f'{TABS(t)}if isinstance(self.{attribute.name}, types.Integer):\n'
216+
o += f'{TABS(t)} {attribute.name} = self.{attribute.name}\n'
217+
o += f'{TABS(t)}elif isinstance(self.{attribute.name}, int):\n'
218+
o += f'{TABS(t)} {attribute.name} = {attribute.type}(self.{attribute.name})\n'
219+
o += f'{TABS(t)}elif isinstance(self.{attribute.name}, str):\n'
220+
o += f'{TABS(t)} {attribute.name} = {attribute.type}.from_mcnp(self.{attribute.name})\n'
221+
elif 'types.Real' in attribute.type:
222+
o += f'{TABS(t)}if isinstance(self.{attribute.name}, types.Real):\n'
223+
o += f'{TABS(t)} {attribute.name} = self.{attribute.name}\n'
224+
o += f'{TABS(t)}elif isinstance(self.{attribute.name}, float) or isinstance(self.{attribute.name}, int):\n'
225+
o += f'{TABS(t)} {attribute.name} = {attribute.type}(self.{attribute.name})\n'
226+
o += f'{TABS(t)}elif isinstance(self.{attribute.name}, str):\n'
227+
o += f'{TABS(t)} {attribute.name} = {attribute.type}.from_mcnp(self.{attribute.name})\n'
228+
else:
229+
o += f'{TABS(t)}if isinstance(self.{attribute.name}, {attribute.type}):\n'
230+
o += f'{TABS(t)} {attribute.name} = self.{attribute.name}\n'
231+
o += f'{TABS(t)}elif isinstance(self.{attribute.name}, str):\n'
232+
o += f'{TABS(t)} {attribute.name} = {attribute.type}.from_mcnp(self.{attribute.name})\n'
233+
234+
o += '\n'
235+
236+
return o.strip()
237+
238+
239+
def ATTRS_ASSIGN(element, t):
240+
o = ''
241+
242+
for attribute in element.attributes:
243+
o += f'{TABS(t)}{attribute.name}={attribute.name},\n'
244+
245+
return o.strip()
246+
247+
132248
# ELEMENT #
133249
def INIT(element):
134250
return f"""
135251
from .option_ import {CAMEL(element.name)}Option_
136252
{''.join(f"from . import {SNAKE(option.name)}\n" if option.options else "" for option in element.options)[:-1]}
137253
{''.join(f'from .{CAMEL(option.name)} import {CAMEL(option.name)}\n' for option in element.options)[:-1]}
254+
{''.join(f'from .{CAMEL(option.name)} import {CAMEL(option.name).split('_')[0]}Builder{f"_{CAMEL(option.name).split('_')[1]}" if len(CAMEL(option.name).split('_')) - 1 else ""}\n' for option in element.options)[:-1]}
138255
139256
__all__ = [
140257
"{CAMEL(element.name)}Option_",
141258
{''.join(f'\t"{SNAKE(option.name)}",\n' if option.options else "" for option in element.options).strip()}
142259
{''.join(f'\t"{CAMEL(option.name)}",\n' for option in element.options).strip()}
260+
{''.join(f'\t"{CAMEL(option.name).split('_')[0]}Builder{f"_{CAMEL(option.name).split('_')[1]}" if len(CAMEL(option.name).split('_')) - 1 else ""}",\n' for option in element.options)[:-1].strip()}
143261
]
144262
"""[1:-1]
145263

@@ -185,6 +303,7 @@ def ELEMENT(element, parent_name, depth):
185303
return f'''
186304
import re
187305
import typing
306+
import dataclasses
188307
189308
import molmass
190309
@@ -199,10 +318,10 @@ def ELEMENT(element, parent_name, depth):
199318
200319
class {CAMEL(element.name)}({f"{CAMEL(parent_name)}Option_, keyword='{element.mnemonic}'" if parent_name else "Card_"}):
201320
"""
202-
Represents INP {element.name} elements.
321+
Represents INP {element.name.split('_')[0]}{f" variation #{element.name.split('_')[1]}"if len(element.name.split('_')) - 1 else ""} elements.
203322
204323
Attributes:
205-
InpError: {element.error}.
324+
{ATTRS_COMMENT(element, 2)}
206325
"""
207326
208327
_ATTRS = {{{ATTRS_DICT(element)}}}
@@ -225,7 +344,31 @@ def __init__(self, {ATTRS_PARAM(element)}):
225344
self.value: typing.Final[types.Tuple] = types.Tuple([{ATTRS_LIST(element)}])\n
226345
{ATTRS_STORE(element, 2)}
227346
228-
{element.extra}
347+
{element.extra.strip()}
348+
@dataclasses.dataclass
349+
class {CAMEL(element.name).split('_')[0]}Builder{f"_{CAMEL(element.name).split('_')[1]}" if len(CAMEL(element.name).split('_')) - 1 else ""}:
350+
"""
351+
Builds ``{CAMEL(element.name)}``.
352+
353+
Attributes:
354+
{ATTRS_COMMENT(element, 2)}
355+
"""
356+
357+
{ATTRS_DATACLASS(element, 1)}
358+
359+
def build(self):
360+
"""
361+
Builds ``{CAMEL(element.name).split('_')[0]}Builder{f"_{CAMEL(element.name).split('_')[1]}" if len(CAMEL(element.name).split('_')) - 1 else ""}`` into ``{CAMEL(element.name)}``.
362+
363+
Returns:
364+
``{CAMEL(element.name)}`` for ``{CAMEL(element.name).split('_')[0]}Builder{f"_{CAMEL(element.name).split('_')[1]}" if len(CAMEL(element.name).split('_')) - 1 else ""}``.
365+
"""
366+
367+
{ATTRS_BUILDER(element, 2)}
368+
369+
return {CAMEL(element.name)}(
370+
{ATTRS_ASSIGN(element, 3)}
371+
)
229372
'''[1:]
230373

231374

@@ -246,11 +389,13 @@ def build_element(element, parent_name, path_dir, depth):
246389

247390
build_element(option, element.name, path_subdir, depth + 1)
248391

249-
if element.name not in {'cell', 'surface', 'comment'} and parent_name != '':
392+
if parent_name != 'alsdkjfhalsdkjf':
250393
path_file = path_dir / f'{CAMEL(element.name)}.py'
251394
with path_file.open('w') as file:
252395
file.write(ELEMENT(element, parent_name, depth - 1))
253396

254397

255398
for card in inp_data.cards.options:
256-
build_element(card, '', pathlib.Path(__file__).parent.parent / 'src/pymcnp/inp', 3)
399+
build_element(
400+
card, 'alsdkjfhalsdkjf', pathlib.Path(__file__).parent.parent / 'src/pymcnp/inp', 3
401+
)

scripts/inp_data.py

+37-4
Original file line numberDiff line numberDiff line change
@@ -544,7 +544,7 @@ def __init__(
544544
type='types.Integer',
545545
description='Displacement vector origin',
546546
optional=True,
547-
)
547+
),
548548
],
549549
),
550550
ElementScheme(
@@ -5780,7 +5780,7 @@ def from_formula(number: int, formulas: dict[str, float], atomic_or_weight: bool
57805780
],
57815781
),
57825782
ElementScheme(
5783-
name='erg',
5783+
name='erg_0',
57845784
mnemonic='erg',
57855785
attributes=[
57865786
AttributeScheme(
@@ -5790,6 +5790,17 @@ def from_formula(number: int, formulas: dict[str, float], atomic_or_weight: bool
57905790
),
57915791
],
57925792
),
5793+
ElementScheme(
5794+
name='erg_1',
5795+
mnemonic='erg',
5796+
attributes=[
5797+
AttributeScheme(
5798+
name='energy',
5799+
type='types.DistributionNumber',
5800+
description='Kinetic energy',
5801+
),
5802+
],
5803+
),
57935804
ElementScheme(
57945805
name='tme_0',
57955806
mnemonic='tme',
@@ -5813,7 +5824,7 @@ def from_formula(number: int, formulas: dict[str, float], atomic_or_weight: bool
58135824
],
58145825
),
58155826
ElementScheme(
5816-
name='dir',
5827+
name='dir_0',
58175828
mnemonic='dir',
58185829
attributes=[
58195830
AttributeScheme(
@@ -5823,6 +5834,17 @@ def from_formula(number: int, formulas: dict[str, float], atomic_or_weight: bool
58235834
),
58245835
],
58255836
),
5837+
ElementScheme(
5838+
name='dir_1',
5839+
mnemonic='dir',
5840+
attributes=[
5841+
AttributeScheme(
5842+
name='cosine',
5843+
type='types.DistributionNumber',
5844+
description='Cosine of the angle between VEC and particle',
5845+
),
5846+
],
5847+
),
58265848
ElementScheme(
58275849
name='vec',
58285850
mnemonic='vec',
@@ -5867,7 +5889,7 @@ def from_formula(number: int, formulas: dict[str, float], atomic_or_weight: bool
58675889
],
58685890
),
58695891
ElementScheme(
5870-
name='rad',
5892+
name='rad_0',
58715893
mnemonic='rad',
58725894
attributes=[
58735895
AttributeScheme(
@@ -5877,6 +5899,17 @@ def from_formula(number: int, formulas: dict[str, float], atomic_or_weight: bool
58775899
),
58785900
],
58795901
),
5902+
ElementScheme(
5903+
name='rad_1',
5904+
mnemonic='rad',
5905+
attributes=[
5906+
AttributeScheme(
5907+
name='radial_distance',
5908+
type='types.DistributionNumber',
5909+
description='Radial distance fo the position from POS or AXS',
5910+
),
5911+
],
5912+
),
58805913
ElementScheme(
58815914
name='ext',
58825915
mnemonic='ext',

src/pymcnp/Inp.py

+79
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import re
22
import typing
3+
import dataclasses
34

45
import pyvista
56

@@ -225,3 +226,81 @@ def draw(self) -> pyvista.PolyData:
225226
vis += _visualization.Visualization(surface.draw())
226227

227228
return vis.data
229+
230+
231+
@dataclasses.dataclass
232+
class InpBuilder:
233+
"""
234+
Builds ``Inp``.
235+
236+
Attributes:
237+
message: INP message.
238+
title: INP title.
239+
cells: INP cell card block.
240+
surfaces: INP surface card block.
241+
data: INP data card block.
242+
other: INP other block.
243+
"""
244+
245+
title: str
246+
cells: dict[str, str | inp.Cell | inp.CellBuilder] = dataclasses.field(
247+
default_factory=lambda _: {}
248+
)
249+
surfaces: dict[str, str | inp.Surface | inp.SurfaceBuilder] = dataclasses.field(
250+
default_factory=lambda _: {}
251+
)
252+
data: dict[str, str | inp.Data | inp.DataBuilder] = dataclasses.field(
253+
default_factory=lambda _: {}
254+
)
255+
message: str = ''
256+
other: str = ''
257+
258+
def build(self):
259+
"""
260+
Builds ``InpBuilder`` into ``Inp``.
261+
262+
Returns:
263+
``Inp`` for ``InpBuilder``.
264+
"""
265+
266+
cells = []
267+
for item in self.cells.values():
268+
if isinstance(item, inp.Cell):
269+
cells.append(item)
270+
elif isinstance(item, str):
271+
cells.append(inp.Cell.from_mcnp(item))
272+
else:
273+
cells.append(item.build())
274+
cells = types.Tuple(cells)
275+
276+
surfaces = []
277+
for item in self.surfaces.values():
278+
if isinstance(item, inp.Surface):
279+
surfaces.append(item)
280+
elif isinstance(item, str):
281+
surfaces.append(inp.Surface.from_mcnp(item))
282+
else:
283+
surfaces.append(item.build())
284+
surfaces = types.Tuple(surfaces)
285+
286+
data = []
287+
for item in self.data.values():
288+
if isinstance(item, inp.Surface):
289+
data.append(item)
290+
elif isinstance(item, str):
291+
data.append(inp.Data.from_mcnp(item))
292+
else:
293+
data.append(item.build())
294+
data = types.Tuple(data)
295+
296+
return Inp(
297+
title=self.title,
298+
message=self.message,
299+
other=self.other,
300+
cells=cells,
301+
cells_comments=types.Tuple([]),
302+
surfaces=surfaces,
303+
surfaces_comments=types.Tuple([]),
304+
data=data,
305+
data_comments=types.Tuple([]),
306+
)

0 commit comments

Comments
 (0)