ncrystal-python 4.1.6__py3-none-any.whl → 4.2.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- NCrystal/__init__.py +3 -3
- NCrystal/_chooks.py +22 -8
- NCrystal/_cli_ncmat2endf.py +337 -0
- NCrystal/_common.py +9 -1
- NCrystal/_miscimpl.py +23 -2
- NCrystal/_ncmat2endf_impl.py +1578 -0
- NCrystal/_ncmatimpl.py +28 -11
- NCrystal/_sabutils.py +100 -0
- NCrystal/cifutils.py +1 -1
- NCrystal/ncmat.py +8 -3
- NCrystal/ncmat2endf.py +313 -0
- NCrystal/plot.py +6 -4
- NCrystal/vdos.py +27 -3
- {ncrystal_python-4.1.6.dist-info → ncrystal_python-4.2.0.dist-info}/METADATA +1 -1
- {ncrystal_python-4.1.6.dist-info → ncrystal_python-4.2.0.dist-info}/RECORD +19 -15
- {ncrystal_python-4.1.6.dist-info → ncrystal_python-4.2.0.dist-info}/WHEEL +1 -1
- {ncrystal_python-4.1.6.dist-info → ncrystal_python-4.2.0.dist-info}/entry_points.txt +1 -0
- {ncrystal_python-4.1.6.dist-info → ncrystal_python-4.2.0.dist-info}/licenses/LICENSE +0 -0
- {ncrystal_python-4.1.6.dist-info → ncrystal_python-4.2.0.dist-info}/top_level.txt +0 -0
NCrystal/__init__.py
CHANGED
|
@@ -48,14 +48,14 @@ additionally also use the following reference in your work:
|
|
|
48
48
|
|
|
49
49
|
For detailed usage conditions and licensing of this open source project, see:
|
|
50
50
|
|
|
51
|
-
https://github.com/mctools/ncrystal/blob/
|
|
52
|
-
https://github.com/mctools/ncrystal/blob/
|
|
51
|
+
https://github.com/mctools/ncrystal/blob/HEAD/NOTICE
|
|
52
|
+
https://github.com/mctools/ncrystal/blob/HEAD/LICENSE
|
|
53
53
|
|
|
54
54
|
"""
|
|
55
55
|
|
|
56
56
|
#NB: Synchronize meta-data below with fields in setup.py+template_setup.py.in meta data:
|
|
57
57
|
__license__ = "Apache 2.0, http://www.apache.org/licenses/LICENSE-2.0"
|
|
58
|
-
__version__ = '4.
|
|
58
|
+
__version__ = '4.2.0'
|
|
59
59
|
__status__ = "Production"
|
|
60
60
|
__author__ = "NCrystal developers (Thomas Kittelmann, Xiao Xiao Cai)"
|
|
61
61
|
__copyright__ = "Copyright 2015-2024 %s"%__author__
|
NCrystal/_chooks.py
CHANGED
|
@@ -319,12 +319,24 @@ def _load(nclib_filename, ncrystal_namespace_protection ):
|
|
|
319
319
|
functions['raw_vdos2gn'] = raw_vdos2gn
|
|
320
320
|
|
|
321
321
|
_ORDERWEIGHTFCTTYPE = ctypes.CFUNCTYPE( _dbl, _uint )
|
|
322
|
-
_raw_vdos2knl = _wrap('
|
|
323
|
-
|
|
322
|
+
_raw_vdos2knl = _wrap('ncrystal_raw_vdos2kernel',None,
|
|
323
|
+
(_dblp,_dblp,_uint,_uint,_dbl,_dbl,_dbl,_uint,
|
|
324
|
+
_ORDERWEIGHTFCTTYPE,_uintp,_uintp,_dblpp,_dblpp,
|
|
325
|
+
_dblpp,_dbl,_dblp),
|
|
326
|
+
hide=True)
|
|
327
|
+
def raw_vdos2knl( egrid, density, scatxs, mass_amu, temperature,
|
|
328
|
+
vdoslux, order_weight_fct, target_emax ):
|
|
324
329
|
_ensure_numpy()
|
|
325
|
-
_egrid
|
|
326
|
-
|
|
327
|
-
|
|
330
|
+
_egrid = _np.asarray(egrid,dtype=float)
|
|
331
|
+
_density = _np.asarray(density,dtype=float)
|
|
332
|
+
_s = _dbl(float(scatxs))
|
|
333
|
+
_m = _dbl(float(mass_amu))
|
|
334
|
+
_t = _dbl(float(temperature))
|
|
335
|
+
_vdl = _uint(int(vdoslux))
|
|
336
|
+
_tgtemax = target_emax or 0.0
|
|
337
|
+
_tgtemax = _dbl( float(_tgtemax if _tgtemax>0.0 else 0.0 ) )
|
|
338
|
+
nalpha, nbeta, suggest_emax = _uint(), _uint(), _dbl()
|
|
339
|
+
agrid, bgrid, sab = _dblp(), _dblp(), _dblp()
|
|
328
340
|
if order_weight_fct:
|
|
329
341
|
def owf(order):
|
|
330
342
|
return float(order_weight_fct( int(order.value
|
|
@@ -336,11 +348,13 @@ def _load(nclib_filename, ncrystal_namespace_protection ):
|
|
|
336
348
|
_owf = ctypes.cast(None, _ORDERWEIGHTFCTTYPE)
|
|
337
349
|
_raw_vdos2knl( ndarray_to_dblp(_egrid), ndarray_to_dblp(_density),
|
|
338
350
|
_uint(len(_egrid)),_uint(len(_density)),
|
|
339
|
-
_s,_m,_t,_vdl,_owf,nalpha, nbeta,
|
|
340
|
-
ctypes.byref(agrid), ctypes.byref(bgrid), ctypes.byref(sab)
|
|
351
|
+
_s,_m,_t,_vdl,_owf, nalpha, nbeta,
|
|
352
|
+
ctypes.byref(agrid), ctypes.byref(bgrid), ctypes.byref(sab),
|
|
353
|
+
_tgtemax, suggest_emax )
|
|
341
354
|
return ( _cptr_to_nparray( agrid, nalpha ),
|
|
342
355
|
_cptr_to_nparray( bgrid, nbeta ),
|
|
343
|
-
_cptr_to_nparray( sab, nalpha.value * nbeta.value )
|
|
356
|
+
_cptr_to_nparray( sab, nalpha.value * nbeta.value ),
|
|
357
|
+
float( suggest_emax.value ) or None )
|
|
344
358
|
functions['raw_vdos2knl'] = raw_vdos2knl
|
|
345
359
|
|
|
346
360
|
def ncrystal_dyninfo_base(key):
|
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
|
|
2
|
+
################################################################################
|
|
3
|
+
## ##
|
|
4
|
+
## This file is part of NCrystal (see https://mctools.github.io/ncrystal/) ##
|
|
5
|
+
## ##
|
|
6
|
+
## Copyright 2015-2025 NCrystal developers ##
|
|
7
|
+
## ##
|
|
8
|
+
## Licensed under the Apache License, Version 2.0 (the "License"); ##
|
|
9
|
+
## you may not use this file except in compliance with the License. ##
|
|
10
|
+
## You may obtain a copy of the License at ##
|
|
11
|
+
## ##
|
|
12
|
+
## http://www.apache.org/licenses/LICENSE-2.0 ##
|
|
13
|
+
## ##
|
|
14
|
+
## Unless required by applicable law or agreed to in writing, software ##
|
|
15
|
+
## distributed under the License is distributed on an "AS IS" BASIS, ##
|
|
16
|
+
## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ##
|
|
17
|
+
## See the License for the specific language governing permissions and ##
|
|
18
|
+
## limitations under the License. ##
|
|
19
|
+
## ##
|
|
20
|
+
################################################################################
|
|
21
|
+
|
|
22
|
+
from ._cliimpl import ( create_ArgumentParser,
|
|
23
|
+
cli_entry_point )
|
|
24
|
+
|
|
25
|
+
longopt_metadata = '--mdata'
|
|
26
|
+
metavar_elastic = 'MODE'
|
|
27
|
+
metavar_matname = 'NAME'
|
|
28
|
+
metavar_metadata = 'DATA'
|
|
29
|
+
longopt_elastic = '--elas'
|
|
30
|
+
longopt_matname = '--name'
|
|
31
|
+
longopt_datenow = '--now'
|
|
32
|
+
longopt_othertemps = '--othertemps'
|
|
33
|
+
|
|
34
|
+
#Examples here so they can be unit tested:
|
|
35
|
+
examples = [
|
|
36
|
+
['Al_sg225.ncmat;temp=350K'],
|
|
37
|
+
['Si_sg227.ncmat;temp=293.6K','-m','MATNUM:Si:99',longopt_datenow],
|
|
38
|
+
['ZnO_sg186_ZincOxide.ncmat;temp=293.15K','-n','ZnO',
|
|
39
|
+
'-e','scaled','-m','MATNUM:Zn:101,O:102'],
|
|
40
|
+
['Bi_sg166.ncmat;comp=inelas;temp=77K','-m','AUTH:J. Doe']
|
|
41
|
+
]
|
|
42
|
+
|
|
43
|
+
def _parseArgs( progname, arglist, return_parser=False ):
|
|
44
|
+
from .ncmat2endf import ( available_elastic_modes,
|
|
45
|
+
default_smin_value,
|
|
46
|
+
default_emax_value )
|
|
47
|
+
from ._common import print
|
|
48
|
+
from argparse import RawTextHelpFormatter
|
|
49
|
+
import textwrap
|
|
50
|
+
import json
|
|
51
|
+
import shlex
|
|
52
|
+
|
|
53
|
+
helpw = 60
|
|
54
|
+
descrw = helpw + 22
|
|
55
|
+
descr_sections = [
|
|
56
|
+
"""Script for creating a set of ENDF-6 thermal scattering files for the
|
|
57
|
+
material described by a particular NCrystal cfg-string.
|
|
58
|
+
""",
|
|
59
|
+
"""
|
|
60
|
+
The script uses the endf-parserpy package from IAEA to format and check
|
|
61
|
+
the syntax of the ENDF-6 file:
|
|
62
|
+
""",
|
|
63
|
+
"""
|
|
64
|
+
G. Schnabel, D. L. Aldama, R. Capote,
|
|
65
|
+
https://doi.org/10.48550/arXiv.2312.08249
|
|
66
|
+
""",
|
|
67
|
+
f"""
|
|
68
|
+
Note that while the handling of multiple temperatures in one ENDF-6
|
|
69
|
+
file is supported via the {longopt_othertemps} keyword, it is not
|
|
70
|
+
recommended. This is because NCrystal computes an optimal (alpha, beta)
|
|
71
|
+
grid for each material and temperature, while the ENDF format imposes
|
|
72
|
+
the same grid on all temperatures.
|
|
73
|
+
""",
|
|
74
|
+
]
|
|
75
|
+
|
|
76
|
+
# NOTICE ^^^^^^^^^^^
|
|
77
|
+
#
|
|
78
|
+
# When updating ncmat2endf there are 2 main doc texts that have to be
|
|
79
|
+
# checked for updates:
|
|
80
|
+
#
|
|
81
|
+
# 1) The ncmat2endf function doc-string in ncmat2endf.py
|
|
82
|
+
# 2) The ncmat2endf CLI --help text in _cli_ncmat2endf.py
|
|
83
|
+
#
|
|
84
|
+
|
|
85
|
+
descr = '\n\n'.join(textwrap.fill(' '.join(e.strip().split()),descrw)
|
|
86
|
+
for e in descr_sections)
|
|
87
|
+
|
|
88
|
+
def exquote(e):
|
|
89
|
+
#prefer " for quoting (for Windows compatibility)
|
|
90
|
+
e = shlex.quote(e)
|
|
91
|
+
if '"' not in e and "'" in e:
|
|
92
|
+
e = e.replace("'",'"')
|
|
93
|
+
if '"' not in e and ',' in e:
|
|
94
|
+
#Add some quotes that shlex did not think necessary:
|
|
95
|
+
e = '"%s"'%e
|
|
96
|
+
return e
|
|
97
|
+
|
|
98
|
+
descr += "\n\nExample invocations:\n\n"
|
|
99
|
+
exw = descrw - len(progname) - 7
|
|
100
|
+
expre=f' $> {progname} '
|
|
101
|
+
for example in examples:
|
|
102
|
+
s=['']
|
|
103
|
+
for e in example:
|
|
104
|
+
e = exquote(e)
|
|
105
|
+
if len(s[-1]+e) > exw:
|
|
106
|
+
s[-1] += ' \\'
|
|
107
|
+
s.append('')
|
|
108
|
+
s[-1] += ' %s'%e
|
|
109
|
+
descr += '%s%s\n'%(expre,s[0])
|
|
110
|
+
for e in s[1:]:
|
|
111
|
+
descr += '%s%s\n'%(' '*len(expre),e)
|
|
112
|
+
descr += '\n'
|
|
113
|
+
|
|
114
|
+
usagestr = (
|
|
115
|
+
f'{progname} CFGSTR [{longopt_elastic} {metavar_elastic}]'
|
|
116
|
+
+ f' [{longopt_matname} {metavar_matname}]'
|
|
117
|
+
+ f' [{longopt_metadata} {metavar_metadata}]\n'
|
|
118
|
+
+ (' '*(len(progname)+8))
|
|
119
|
+
+ '[<<additional options described below>>]'
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
parser = create_ArgumentParser( prog = progname,
|
|
123
|
+
description=descr.strip()+'\n',
|
|
124
|
+
usage=usagestr,
|
|
125
|
+
formatter_class=RawTextHelpFormatter )
|
|
126
|
+
def wrap(t):
|
|
127
|
+
return textwrap.fill(t,width=helpw)
|
|
128
|
+
|
|
129
|
+
required_args = parser.add_argument_group('required arguments')
|
|
130
|
+
required_args.add_argument('CFGSTR',
|
|
131
|
+
help=wrap('NCrystal cfg-string defining the'
|
|
132
|
+
' material.'))
|
|
133
|
+
|
|
134
|
+
ba = parser.add_argument_group('Commonly used arguments')
|
|
135
|
+
ba.add_argument( '-n', longopt_matname, metavar=metavar_matname,
|
|
136
|
+
help=wrap('Name of the material to be processed.'
|
|
137
|
+
'If set ENDF files will be named '
|
|
138
|
+
f'tsl_element_in_<{metavar_matname}>.endf.'))
|
|
139
|
+
elasmode_default = 'scaled'
|
|
140
|
+
assert elasmode_default in available_elastic_modes
|
|
141
|
+
elasmode_other = list(e for e in available_elastic_modes
|
|
142
|
+
if e != elasmode_default )
|
|
143
|
+
assert len(elasmode_other)==2
|
|
144
|
+
ba.add_argument('-e', longopt_elastic,metavar=metavar_elastic,
|
|
145
|
+
help=wrap('Approximation used for the elastic component'
|
|
146
|
+
f' (default "{elasmode_default}, other options'
|
|
147
|
+
f' are "{elasmode_other[0]}" and'
|
|
148
|
+
f' "{elasmode_other[1]}").'
|
|
149
|
+
' See DOI:10.1016/j.nima.2021.166227 for'
|
|
150
|
+
' meaning of modes.'),
|
|
151
|
+
type=str, choices=available_elastic_modes,
|
|
152
|
+
default=elasmode_default)
|
|
153
|
+
ba.add_argument(longopt_metadata,default={},
|
|
154
|
+
help=wrap('JSON dictionary containing ENDF-6'
|
|
155
|
+
f' metadata. Run with {longopt_metadata}=help '
|
|
156
|
+
'for more information.'))
|
|
157
|
+
ba.add_argument('-m',metavar='KEY:VAL', dest='mdata_kvlist',
|
|
158
|
+
action='append', nargs='+',
|
|
159
|
+
help=wrap('Add metadata entries. Run with '
|
|
160
|
+
f'{longopt_metadata}=help for more info.'))
|
|
161
|
+
ba.add_argument(longopt_datenow,action='store_true',
|
|
162
|
+
help=wrap('Set metadata fields EDATE, DDATE and RDATE'
|
|
163
|
+
' to current date.'))
|
|
164
|
+
|
|
165
|
+
parser.add_argument('-v','--verbose', action='count',default=0,
|
|
166
|
+
help=wrap('Increase verbosity. Specify twice'
|
|
167
|
+
' for additional verbosity.'))
|
|
168
|
+
parser.add_argument('--quiet','-q',default=False,action='store_true',
|
|
169
|
+
help=wrap('Silence non-error output.'))
|
|
170
|
+
ba.add_argument('-d', '--dir', default = '.', metavar='PATH', dest='outdir',
|
|
171
|
+
help=wrap('Directory for output files (default: current).'))
|
|
172
|
+
ba.add_argument('-i','--index', default = '',
|
|
173
|
+
metavar='FILE', dest='jsonindex',
|
|
174
|
+
help=wrap('Story summary of output in FILE (JSON format).'))
|
|
175
|
+
ba.add_argument('-f', '--force',action='store_true',
|
|
176
|
+
help=wrap('Overwrite output files if'
|
|
177
|
+
' they already exist (danger!)'))
|
|
178
|
+
|
|
179
|
+
expert_args = parser.add_argument_group('Advanced expert-only arguments')
|
|
180
|
+
expert_args.add_argument(longopt_othertemps,metavar='TVALS',
|
|
181
|
+
nargs='+',
|
|
182
|
+
type=float,
|
|
183
|
+
help=wrap('Additional temperatures to process. As'
|
|
184
|
+
' noted above this is not normally'
|
|
185
|
+
' recommended, and it is preferred'
|
|
186
|
+
' to invoke the script for each'
|
|
187
|
+
' temperature independently using the'
|
|
188
|
+
' "temp" keyword in the cfg-string.') )
|
|
189
|
+
expert_args.add_argument('--smin',metavar='VALUE',
|
|
190
|
+
type=float, default=default_smin_value,
|
|
191
|
+
help=wrap('Minimum value of S(alpha, beta) stored'
|
|
192
|
+
f' (default: {default_smin_value})'))
|
|
193
|
+
expert_args.add_argument('--emax',
|
|
194
|
+
type=float, default=default_emax_value,
|
|
195
|
+
help=wrap('Maximum neutron energy covered by'
|
|
196
|
+
' the kernels'
|
|
197
|
+
f' (default: {default_emax_value:g}eV)')
|
|
198
|
+
)
|
|
199
|
+
expert_args.add_argument('--asymsab',action='store_true',
|
|
200
|
+
help=wrap('Store S(a,b) in asymmetric form.'))
|
|
201
|
+
expert_args.add_argument('--totsab',action='store_true',
|
|
202
|
+
help=wrap('Store S(a,b) branches for positive'
|
|
203
|
+
' and negative beta'))
|
|
204
|
+
|
|
205
|
+
if return_parser:
|
|
206
|
+
return parser
|
|
207
|
+
|
|
208
|
+
#Avoid annoying CFGSTR-missing error when ppl use --mdata=help:
|
|
209
|
+
is_mdata_help = False
|
|
210
|
+
if f'{longopt_metadata}=help' in arglist:
|
|
211
|
+
is_mdata_help = True
|
|
212
|
+
elif longopt_metadata in arglist and 'help' in arglist:
|
|
213
|
+
if arglist.index(longopt_metadata)+1==arglist.index('help'):
|
|
214
|
+
is_mdata_help=True
|
|
215
|
+
if is_mdata_help:
|
|
216
|
+
arglist = [f'{longopt_metadata}=help','dummy']
|
|
217
|
+
|
|
218
|
+
args=parser.parse_args(arglist)
|
|
219
|
+
if args.mdata:
|
|
220
|
+
if args.mdata == 'help':
|
|
221
|
+
print(gen_metadata_doc())
|
|
222
|
+
raise SystemExit(0)
|
|
223
|
+
try:
|
|
224
|
+
args.mdata = json.loads(args.mdata)
|
|
225
|
+
except json.JSONDecodeError:
|
|
226
|
+
parser.error(f'Argument to {longopt_metadata} must be a JSON'
|
|
227
|
+
' dictionary of key, value pairs')
|
|
228
|
+
else:
|
|
229
|
+
if not isinstance(args.mdata,dict):
|
|
230
|
+
parser.error(f'Argument to {longopt_metadata} must be a JSON'
|
|
231
|
+
' dictionary of key, value pairs')
|
|
232
|
+
assert isinstance(args.mdata,dict)
|
|
233
|
+
for ee in args.mdata_kvlist or []:
|
|
234
|
+
for e in ee:
|
|
235
|
+
kv = list(_.strip() for _ in e.split(':',1))
|
|
236
|
+
if not len(kv)==2 or not kv[0]:
|
|
237
|
+
parser.error(f'Invalid parameter for -m: {repr(e)}')
|
|
238
|
+
args.mdata[kv[0]] = kv[1]
|
|
239
|
+
args.m = None
|
|
240
|
+
|
|
241
|
+
#map verbosity to 0...3 needed for Python API:
|
|
242
|
+
if args.quiet:
|
|
243
|
+
if args.verbose:
|
|
244
|
+
parser.error('Inconsistent usage of --quiet and --verbose flags')
|
|
245
|
+
else:
|
|
246
|
+
args.verbose = min( 3, args.verbose+1 )
|
|
247
|
+
|
|
248
|
+
if args.jsonindex:
|
|
249
|
+
import pathlib
|
|
250
|
+
args.jsonindex = pathlib.Path(args.jsonindex)
|
|
251
|
+
if args.jsonindex.is_file():
|
|
252
|
+
if not args.force:
|
|
253
|
+
parser.error('File already exists (run with --force to'
|
|
254
|
+
f' overwrite): {args.jsonindex}')
|
|
255
|
+
args.jsonindex.unlink()
|
|
256
|
+
assert not args.jsonindex.is_file()
|
|
257
|
+
if not args.jsonindex.parent.is_dir():
|
|
258
|
+
parser.error('Directory does not exist: {args.jsonindex.parent}')
|
|
259
|
+
args.jsonindex = args.jsonindex.absolute()
|
|
260
|
+
|
|
261
|
+
return args
|
|
262
|
+
|
|
263
|
+
def create_argparser_for_sphinx( progname ):
|
|
264
|
+
return _parseArgs(progname,[],return_parser=True)
|
|
265
|
+
|
|
266
|
+
@cli_entry_point
|
|
267
|
+
def main( progname, arglist ):
|
|
268
|
+
args = _parseArgs( progname, arglist )
|
|
269
|
+
if args.quiet:
|
|
270
|
+
from ._common import ( modify_ncrystal_print_fct_ctxmgr,
|
|
271
|
+
WarningSpy )
|
|
272
|
+
with modify_ncrystal_print_fct_ctxmgr('block'):
|
|
273
|
+
with WarningSpy( block = True ):
|
|
274
|
+
_main_impl(args)
|
|
275
|
+
else:
|
|
276
|
+
_main_impl(args)
|
|
277
|
+
|
|
278
|
+
def _main_impl( args ):
|
|
279
|
+
from .ncmat2endf import EndfMetaData, ncmat2endf
|
|
280
|
+
metadata = EndfMetaData()
|
|
281
|
+
if args.mdata:
|
|
282
|
+
metadata.update_from_dict(args.mdata)
|
|
283
|
+
if args.now:
|
|
284
|
+
metadata.set_all_dates_as_now()
|
|
285
|
+
lasym = 0
|
|
286
|
+
if args.totsab:
|
|
287
|
+
lasym = 1
|
|
288
|
+
if args.asymsab:
|
|
289
|
+
lasym += 2
|
|
290
|
+
r = ncmat2endf( args.CFGSTR,
|
|
291
|
+
material_name = args.name,
|
|
292
|
+
endf_metadata = metadata,
|
|
293
|
+
othertemps = args.othertemps,
|
|
294
|
+
elastic_mode = args.elas,
|
|
295
|
+
force = args.force,
|
|
296
|
+
smin = args.smin,
|
|
297
|
+
emax = args.emax,
|
|
298
|
+
lasym = lasym,
|
|
299
|
+
verbosity = args.verbose,
|
|
300
|
+
outdir = args.outdir )
|
|
301
|
+
if args.jsonindex:
|
|
302
|
+
import json
|
|
303
|
+
r_json = json.dumps( r, indent = 4 ).rstrip() + '\n'
|
|
304
|
+
print(f'Writing index file: {args.jsonindex.name}')
|
|
305
|
+
args.jsonindex.write_text( r_json )
|
|
306
|
+
|
|
307
|
+
def gen_metadata_doc():
|
|
308
|
+
from ._ncmat2endf_impl import _impl_get_metadata_params_and_docs
|
|
309
|
+
import textwrap
|
|
310
|
+
|
|
311
|
+
d = _impl_get_metadata_params_and_docs()
|
|
312
|
+
assert 'LIBNAME' in d
|
|
313
|
+
assert 'ALAB' in d
|
|
314
|
+
txt = ''
|
|
315
|
+
w = 80
|
|
316
|
+
def section( x ):
|
|
317
|
+
return textwrap.fill(' '.join(x.strip().split()),w)
|
|
318
|
+
|
|
319
|
+
txt += section(
|
|
320
|
+
f"""Meta-data for ENDF can be provided by the {longopt_metadata}
|
|
321
|
+
option, by specifying a JSON dictionary like:"""
|
|
322
|
+
)
|
|
323
|
+
txt+=('''\n\n %s='{ "LIBNAME" : "MySuperLib"'''%longopt_metadata
|
|
324
|
+
+''', "ALAB" : "MySuperLab" }'\n\n''')
|
|
325
|
+
txt += section(
|
|
326
|
+
"""Or by adding individual items with the -m option like:"""
|
|
327
|
+
)
|
|
328
|
+
txt+=('''\n\n -m LIBNAME:MySuperLib -m AUTH:"J. Chadwick"\n\n''')
|
|
329
|
+
txt += section('The list of supported meta-data'
|
|
330
|
+
' keys and their meaning is:')
|
|
331
|
+
txt += '\n\n'
|
|
332
|
+
kmax = max(len(k) for k in d)
|
|
333
|
+
for k, v in d.items():
|
|
334
|
+
s = f' {k.rjust(kmax)} : '
|
|
335
|
+
for i,e in enumerate(textwrap.fill( v, width=w-len(s) ).splitlines()):
|
|
336
|
+
txt += (' '*len(s) if i else s) + e + '\n'
|
|
337
|
+
return txt
|
NCrystal/_common.py
CHANGED
|
@@ -130,7 +130,15 @@ def warn(msg):
|
|
|
130
130
|
"""Emit NCrystalUserWarning via standard warnings.warn function"""
|
|
131
131
|
from .exceptions import NCrystalUserWarning
|
|
132
132
|
import warnings
|
|
133
|
-
|
|
133
|
+
m = str(msg)
|
|
134
|
+
if _add_warn_counts_to_msgs[0]:
|
|
135
|
+
_add_warn_counts_to_msgs[1] += 1
|
|
136
|
+
m = '%s [warn#%i]'%(m,_add_warn_counts_to_msgs[1])
|
|
137
|
+
warnings.warn( NCrystalUserWarning(m), stacklevel = 2 )
|
|
138
|
+
|
|
139
|
+
#Hook to avoid repeated warnings to be silenced during unit tests, by appending
|
|
140
|
+
#a warning number to them:
|
|
141
|
+
_add_warn_counts_to_msgs = [False,0]
|
|
134
142
|
|
|
135
143
|
class WarningSpy:
|
|
136
144
|
"""Context manager which spies on any warnings emitted via warnings
|
NCrystal/_miscimpl.py
CHANGED
|
@@ -342,13 +342,34 @@ def _anyvdos_init( class_AnyVDOS, anyvdos_extract_d, data, fmt, label ):
|
|
|
342
342
|
return MappingProxyType( d )
|
|
343
343
|
|
|
344
344
|
def detect_scatcomps( standard_comp_types, matsrc ):
|
|
345
|
+
from .exceptions import NCBadInput, NCCalcError
|
|
345
346
|
if matsrc.is_preloaded:
|
|
346
347
|
from .exceptions import NCBadInput
|
|
347
348
|
raise NCBadInput('detect_scattering_components can not be used'
|
|
348
349
|
' with preloaded material sources')
|
|
349
350
|
res=[]
|
|
350
351
|
for ct in standard_comp_types:
|
|
351
|
-
|
|
352
|
-
|
|
352
|
+
def load(extra = None):
|
|
353
|
+
p = f'comp={ct}'
|
|
354
|
+
if extra is not None:
|
|
355
|
+
p += f';{extra}'
|
|
356
|
+
return matsrc.load( extra_cfg_params = p,
|
|
357
|
+
doInfo = False,
|
|
358
|
+
doAbsorption = False )
|
|
359
|
+
m = None
|
|
360
|
+
if ct == 'inelas':
|
|
361
|
+
#For inelas component first we try to see if we can get away with
|
|
362
|
+
#using a potentially smaller vdoslux than is actually used. This is
|
|
363
|
+
#not a great solution, but in the absence of deeper changes to
|
|
364
|
+
#NCrystal processes, this seems a reasonable compromise.
|
|
365
|
+
try:
|
|
366
|
+
m = load('vdoslux=0')
|
|
367
|
+
except NCCalcError as e:
|
|
368
|
+
if not str(e).startswith('VDOS expansion too slow'):
|
|
369
|
+
raise e
|
|
370
|
+
m = None
|
|
371
|
+
if not m:
|
|
372
|
+
m = load()
|
|
373
|
+
if not m.scatter.isNull():
|
|
353
374
|
res.append(ct)
|
|
354
375
|
return res
|