kdsource 0.2.0__py3-none-win_amd64.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.
- kdsource/__init__.py +40 -0
- kdsource/_chooks.py +101 -0
- kdsource/_chooks_loadlib.py +34 -0
- kdsource/_cli_config.py +55 -0
- kdsource/_cli_resample.py +38 -0
- kdsource/_fact_dos_data.py +194 -0
- kdsource/api.py +50 -0
- kdsource/config.py +121 -0
- kdsource/data/include/kdsource/geom.h +99 -0
- kdsource/data/include/kdsource/kdsource.h +88 -0
- kdsource/data/include/kdsource/plist.h +43 -0
- kdsource/data/include/kdsource/utils.h +40 -0
- kdsource/data/lib/kdsource.lib +0 -0
- kdsource/geom.py +1163 -0
- kdsource/kde.py +357 -0
- kdsource/kdsource.py +923 -0
- kdsource/plist.py +429 -0
- kdsource/resample.py +49 -0
- kdsource/stats.py +265 -0
- kdsource/summary.py +174 -0
- kdsource/surfsource.py +1223 -0
- kdsource/tally.py +507 -0
- kdsource/test.py +140 -0
- kdsource/utils.py +156 -0
- kdsource/writemcpl.py +74 -0
- kdsource-0.2.0.data/scripts/kdsource.dll +0 -0
- kdsource-0.2.0.dist-info/METADATA +107 -0
- kdsource-0.2.0.dist-info/RECORD +32 -0
- kdsource-0.2.0.dist-info/WHEEL +5 -0
- kdsource-0.2.0.dist-info/entry_points.txt +5 -0
- kdsource-0.2.0.dist-info/licenses/LICENSE +674 -0
- kdsource-0.2.0.dist-info/licenses/third_party/LICENSE_libxml2 +24 -0
kdsource/__init__.py
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
"""Python module for creating and optimizing KDSource objects.
|
|
4
|
+
|
|
5
|
+
KDSource's are particle sources for Monte Carlo radiation transport
|
|
6
|
+
simulations. The full distribution and documentation can be found in the
|
|
7
|
+
project GitHub page:
|
|
8
|
+
|
|
9
|
+
https://github.com/KDSource/KDSource
|
|
10
|
+
|
|
11
|
+
A KDSource object is based on a particle list in MCPL format (see
|
|
12
|
+
https://mctools.github.io/mcpl/), on which a Kernel Density Estimation
|
|
13
|
+
(KDE) is applied, using KDEpy library (see
|
|
14
|
+
https://github.com/tommyod/KDEpy).
|
|
15
|
+
|
|
16
|
+
With kdsource Python library you can create, optimize, and export
|
|
17
|
+
KDSource objects as XML files. These files can be later used as
|
|
18
|
+
distributional sources in other Monte Carlo simulations, using the tools
|
|
19
|
+
available in the full distribution.
|
|
20
|
+
|
|
21
|
+
If you use KDSource tools in your work, please add the following
|
|
22
|
+
reference:
|
|
23
|
+
|
|
24
|
+
Abbate, O. I., Schmidt, N. S., Prieto, Z. M., Robledo, J. I.,
|
|
25
|
+
Dawidowski, J., Márquez, A. A., & Márquez Damián, J. I. KDSource,
|
|
26
|
+
a tool for the generation of Monte Carlo particle sources using
|
|
27
|
+
kernel density estimation [Computer software].
|
|
28
|
+
https://github.com/KDSource/KDSource
|
|
29
|
+
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
__version__ = "0.2.0"
|
|
33
|
+
versionint = int('2000')
|
|
34
|
+
version = ( int('0'),
|
|
35
|
+
int('2'),
|
|
36
|
+
int('0') )
|
|
37
|
+
__author__ = "KDSource"
|
|
38
|
+
|
|
39
|
+
#NOTE: Keep __init__.py essentially empty. In particular, no import statements
|
|
40
|
+
#here.
|
kdsource/_chooks.py
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
def _str2cstr(s):
|
|
2
|
+
#converts any string (str,bytes,unicode,path) to bytes
|
|
3
|
+
if hasattr(s,'__fspath__'):
|
|
4
|
+
s = str(s)
|
|
5
|
+
try:
|
|
6
|
+
return s if isinstance(s,bytes) else s.encode('utf8')
|
|
7
|
+
except UnicodeEncodeError as e:
|
|
8
|
+
from .exceptions import NCBadInput
|
|
9
|
+
raise NCBadInput("Only unicode strings are supported") from e
|
|
10
|
+
|
|
11
|
+
def _cstr2str(s):
|
|
12
|
+
#converts bytes object to str
|
|
13
|
+
try:
|
|
14
|
+
return s if isinstance(s,str) else s.decode('utf8')
|
|
15
|
+
except UnicodeDecodeError as e:
|
|
16
|
+
from .exceptions import NCBadInput
|
|
17
|
+
raise NCBadInput("Only UTF8-encoded C-strings are supported") from e
|
|
18
|
+
|
|
19
|
+
__cache_fcts=[None]
|
|
20
|
+
def _load_fcts():
|
|
21
|
+
if __cache_fcts[0] is not None:
|
|
22
|
+
return __cache_fcts[0]
|
|
23
|
+
from ._chooks_loadlib import _loadlib_kdsource
|
|
24
|
+
import ctypes
|
|
25
|
+
allfcts = {}
|
|
26
|
+
lib = _loadlib_kdsource()
|
|
27
|
+
|
|
28
|
+
###### resample_to_mcpl
|
|
29
|
+
kds_rng_fct_t = ctypes.CFUNCTYPE( ctypes.c_double )
|
|
30
|
+
rawfct_rs = lib.kdsource_resample_to_mcpl
|
|
31
|
+
rawfct_rs.restype=None
|
|
32
|
+
rawfct_rs.argtypes=( kds_rng_fct_t,
|
|
33
|
+
ctypes.c_char_p,
|
|
34
|
+
ctypes.c_char_p,
|
|
35
|
+
ctypes.c_uint64 )
|
|
36
|
+
def fct_rs( rng_fct, kds_sourcefile, destination_mcpl, nout ):
|
|
37
|
+
rawfct_rs( kds_rng_fct_t(rng_fct),
|
|
38
|
+
_str2cstr(kds_sourcefile),
|
|
39
|
+
_str2cstr(destination_mcpl),
|
|
40
|
+
ctypes.c_uint64(nout) )
|
|
41
|
+
allfcts['resample_to_mcpl'] = fct_rs
|
|
42
|
+
|
|
43
|
+
###### write_mcpl
|
|
44
|
+
dblptr = ctypes.POINTER(ctypes.c_double)
|
|
45
|
+
int32ptr = ctypes.POINTER(ctypes.c_int32)
|
|
46
|
+
uint32ptr = ctypes.POINTER(ctypes.c_uint32)
|
|
47
|
+
rawfct_wm = lib.kdsource_write_mcpl
|
|
48
|
+
rawfct_wm.restype = None
|
|
49
|
+
rawfct_wm.argtypes=( ctypes.c_char_p,ctypes.c_uint64,ctypes.c_uint,
|
|
50
|
+
dblptr,dblptr,dblptr,
|
|
51
|
+
dblptr,dblptr,dblptr,dblptr,dblptr,dblptr,int32ptr,
|
|
52
|
+
dblptr,dblptr,dblptr, uint32ptr)
|
|
53
|
+
def get_ndarray_to_cptr():
|
|
54
|
+
import numpy as np
|
|
55
|
+
def ndarray_fix_type(arr, dtypename):
|
|
56
|
+
a = np.asarray(arr)
|
|
57
|
+
dt = np.dtype(dtypename)
|
|
58
|
+
if a.dtype == dt and a.flags['C_CONTIGUOUS']:
|
|
59
|
+
return a
|
|
60
|
+
return a.astype(dt, copy=True)
|
|
61
|
+
def ndarray_to_cptr(keepalive,a,dtypename='float64',cptr=dblptr):
|
|
62
|
+
keepalive.append( ndarray_fix_type(a,dtypename) )
|
|
63
|
+
return keepalive[-1].ctypes.data_as(cptr)
|
|
64
|
+
return ndarray_to_cptr
|
|
65
|
+
def fct_wm( filename, nparticles,
|
|
66
|
+
ekin, x, y, z, ux, uy, uz, time, weight, pdgcode,
|
|
67
|
+
polx, poly, polz, userflags, double_prec ):
|
|
68
|
+
import numbers
|
|
69
|
+
flags = 1 if double_prec else 0
|
|
70
|
+
keepalive=[]
|
|
71
|
+
a2c = get_ndarray_to_cptr()
|
|
72
|
+
if isinstance(pdgcode, numbers.Integral):
|
|
73
|
+
flags += 2
|
|
74
|
+
pdgcode_array = (ctypes.c_int32 * 1)(int(pdgcode))
|
|
75
|
+
pdgcode_arg = ctypes.cast(pdgcode_array, int32ptr)
|
|
76
|
+
else:
|
|
77
|
+
pdgcode_arg = a2c(keepalive,pdgcode,'int32',int32ptr)
|
|
78
|
+
if isinstance(weight, numbers.Number):
|
|
79
|
+
flags += 4
|
|
80
|
+
weight_array = (ctypes.c_double * 1)(float(weight))
|
|
81
|
+
weight_arg = ctypes.cast(weight_array, dblptr)
|
|
82
|
+
else:
|
|
83
|
+
weight_arg = a2c(keepalive,weight)
|
|
84
|
+
|
|
85
|
+
c_polx = a2c(keepalive,polx) if polx is not None else None
|
|
86
|
+
c_poly = a2c(keepalive,poly) if poly is not None else None
|
|
87
|
+
c_polz = a2c(keepalive,polz) if polz is not None else None
|
|
88
|
+
c_userflags = ( a2c(keepalive,pdgcode,'uint32',uint32ptr)
|
|
89
|
+
if userflags is not None else None )
|
|
90
|
+
rawfct_wm( _str2cstr(filename),
|
|
91
|
+
ctypes.c_uint64(nparticles),
|
|
92
|
+
ctypes.c_uint(flags),
|
|
93
|
+
a2c(keepalive,ekin),
|
|
94
|
+
a2c(keepalive,x), a2c(keepalive,y), a2c(keepalive,z),
|
|
95
|
+
a2c(keepalive,ux), a2c(keepalive,uy), a2c(keepalive,uz),
|
|
96
|
+
a2c(keepalive,time), weight_arg, pdgcode_arg,
|
|
97
|
+
c_polx, c_poly, c_polz, c_userflags )
|
|
98
|
+
allfcts['write_mcpl'] = fct_wm
|
|
99
|
+
|
|
100
|
+
__cache_fcts[0]=allfcts
|
|
101
|
+
return __cache_fcts[0]
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
_loadlib_cache = [None,None]
|
|
2
|
+
def _loadlib_kdsource():
|
|
3
|
+
if _loadlib_cache[1]:
|
|
4
|
+
return _loadlib_cache[1]
|
|
5
|
+
from .config import config
|
|
6
|
+
_loadlib_cache[0] = _loadlib_frompath(_get_mcpl_shlibpath())
|
|
7
|
+
_loadlib_cache[1] = _loadlib_frompath(config('shlibpath'))
|
|
8
|
+
return _loadlib_cache[1]
|
|
9
|
+
|
|
10
|
+
def _loadlib_mcpl():
|
|
11
|
+
if _loadlib_cache[0] is None:
|
|
12
|
+
_loadlib_kdsource()
|
|
13
|
+
return _loadlib_cache[0]
|
|
14
|
+
|
|
15
|
+
def _get_mcpl_shlibpath():
|
|
16
|
+
import subprocess
|
|
17
|
+
rv = subprocess.run( ['mcpl-config','--show','shlibpath'],
|
|
18
|
+
check = True, capture_output = True )
|
|
19
|
+
if rv.returncode or rv.stderr:
|
|
20
|
+
raise RuntimeError('Problems invoking mcpl-config for shlibpath')
|
|
21
|
+
import pathlib
|
|
22
|
+
return pathlib.Path(rv.stdout.decode().strip()).absolute().resolve()
|
|
23
|
+
|
|
24
|
+
def _loadlib_frompath(libpath):
|
|
25
|
+
import ctypes
|
|
26
|
+
try:
|
|
27
|
+
lib = ctypes.CDLL(libpath)
|
|
28
|
+
except TypeError:
|
|
29
|
+
lib = None
|
|
30
|
+
if lib is None:
|
|
31
|
+
#On Windows, providing a Path rather than str can yield TypeError:
|
|
32
|
+
lib = ctypes.CDLL(str(libpath))
|
|
33
|
+
return lib
|
|
34
|
+
|
kdsource/_cli_config.py
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
|
|
2
|
+
def parse_args(argv=None):
|
|
3
|
+
from argparse import ArgumentParser
|
|
4
|
+
from .config import config_items
|
|
5
|
+
import textwrap
|
|
6
|
+
def wrap(t,w=59):
|
|
7
|
+
return textwrap.fill( ' '.join(t.split()), width=w )
|
|
8
|
+
|
|
9
|
+
parser = ArgumentParser(
|
|
10
|
+
description
|
|
11
|
+
='Provide basic information about KDSource installation'
|
|
12
|
+
)
|
|
13
|
+
parser.add_argument('-v','--version',action='store_true',
|
|
14
|
+
help=wrap("""Show the KDSource version number and
|
|
15
|
+
exit."""))
|
|
16
|
+
parser.add_argument('-i','--intversion',action='store_true',
|
|
17
|
+
help=wrap("""Show KDSource version encoded into
|
|
18
|
+
single integral number (e.g. v1.2.3 is 1002003) and
|
|
19
|
+
exit."""))
|
|
20
|
+
parser.add_argument('-s','--summary',action='store_true',
|
|
21
|
+
help=wrap("""Print summary information about
|
|
22
|
+
installation and exit. This displays all the
|
|
23
|
+
information that is otherwise available via the --show
|
|
24
|
+
flag."""))
|
|
25
|
+
parser.add_argument("--show",metavar="ITEM", choices=['list']+config_items,
|
|
26
|
+
help=wrap("""Print value of the requested information
|
|
27
|
+
ITEM for the current NCrystal installation and exit. Run
|
|
28
|
+
with "--show list" to get a list of available ITEM
|
|
29
|
+
values."""))
|
|
30
|
+
return parser.parse_args(argv)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def main(argv=None):
|
|
34
|
+
from .config import summary, config, config_items
|
|
35
|
+
args = parse_args(argv)
|
|
36
|
+
if args.version:
|
|
37
|
+
print(config('version'))
|
|
38
|
+
elif args.intversion:
|
|
39
|
+
print(config('intversion'))
|
|
40
|
+
elif args.summary:
|
|
41
|
+
summary()
|
|
42
|
+
elif args.show:
|
|
43
|
+
if args.show == 'list':
|
|
44
|
+
for c in sorted(config_items):
|
|
45
|
+
print(c)
|
|
46
|
+
elif args.show not in config_items:
|
|
47
|
+
raise SystemExit('ERROR: Unknown configuration item "%s"'%args.show)
|
|
48
|
+
else:
|
|
49
|
+
print(config(args.show))
|
|
50
|
+
else:
|
|
51
|
+
summary()
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
if __name__ == '__main__':
|
|
55
|
+
main()
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
|
|
2
|
+
def parse_args(argv=None):
|
|
3
|
+
from argparse import ArgumentParser
|
|
4
|
+
import textwrap
|
|
5
|
+
def wrap(t,w=59):
|
|
6
|
+
return textwrap.fill( ' '.join(t.split()), width=w )
|
|
7
|
+
|
|
8
|
+
parser = ArgumentParser(
|
|
9
|
+
description=wrap("""Generate new MCPL files based upon an existing
|
|
10
|
+
kernel density estimate XML file.""",
|
|
11
|
+
79 )
|
|
12
|
+
)
|
|
13
|
+
parser.add_argument('kdefile',metavar='KDEFILE',
|
|
14
|
+
help=wrap("""Kernel Density Estimate .xml file generated
|
|
15
|
+
via KDSource python interface."""))
|
|
16
|
+
parser.add_argument('outmcpl',metavar='OUTMCPL',
|
|
17
|
+
help=wrap("""Name of MCPL file which will be created."""))
|
|
18
|
+
parser.add_argument('nparticles',metavar='NPARTICLES',type=int,
|
|
19
|
+
help=wrap("""Number of particles to sample and place in
|
|
20
|
+
OUTMCPL."""))
|
|
21
|
+
parser.add_argument('-s','--seed',metavar='SEED',type=int,
|
|
22
|
+
help=wrap("""Seed value of Number of particles to sample
|
|
23
|
+
and place in OUTMCPL. If not set, a random seed is
|
|
24
|
+
generated (based on bytes from os.urandom)."""))
|
|
25
|
+
parser.add_argument('-f','--force',action='store_true',
|
|
26
|
+
help=wrap("""Will overwrite existing file if it already
|
|
27
|
+
exists."""))
|
|
28
|
+
|
|
29
|
+
return parser.parse_args(argv)
|
|
30
|
+
|
|
31
|
+
def main(argv=None):
|
|
32
|
+
from .resample import resample_to_mcpl
|
|
33
|
+
args = parse_args(argv)
|
|
34
|
+
resample_to_mcpl( args.kdefile, args.outmcpl, args.nparticles,
|
|
35
|
+
force=args.force, rng = args.seed )
|
|
36
|
+
|
|
37
|
+
if __name__ == '__main__':
|
|
38
|
+
main()
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
_cache = {}
|
|
2
|
+
def load(datakey):
|
|
3
|
+
if datakey in _cache:
|
|
4
|
+
return _cache[datakey]
|
|
5
|
+
import numpy
|
|
6
|
+
_cache[datakey] = numpy.fromstring(_data[datakey], unpack=True, sep=None)
|
|
7
|
+
return _cache[datakey]
|
|
8
|
+
|
|
9
|
+
_data = {
|
|
10
|
+
'ARN_neutron' :
|
|
11
|
+
"""0. 0.0
|
|
12
|
+
2.53E-02 1.06E+01
|
|
13
|
+
2.00E+03 7.70E+00
|
|
14
|
+
2.50E+04 1.93E+01
|
|
15
|
+
1.44E+05 1.27E+02
|
|
16
|
+
2.50E+05 2.03E+02
|
|
17
|
+
5.65E+05 3.43E+02
|
|
18
|
+
1.20E+06 4.25E+02
|
|
19
|
+
2.50E+06 4.16E+02
|
|
20
|
+
2.80E+06 4.13E+02
|
|
21
|
+
3.20E+06 4.11E+02
|
|
22
|
+
5.00E+06 4.05E+02
|
|
23
|
+
1.48E+07 5.36E+02
|
|
24
|
+
1.90E+07 5.84E+02
|
|
25
|
+
5.00E+07 5.84E+02
|
|
26
|
+
""",
|
|
27
|
+
'ARN_photon' :
|
|
28
|
+
"""0.0 0.0
|
|
29
|
+
1.00E+04 6.10E-02
|
|
30
|
+
1.50E+04 8.30E-01
|
|
31
|
+
2.00E+04 1.05E+00
|
|
32
|
+
3.00E+04 8.10E-01
|
|
33
|
+
4.00E+04 6.40E-01
|
|
34
|
+
5.00E+04 5.50E-01
|
|
35
|
+
6.00E+04 5.10E-01
|
|
36
|
+
8.00E+04 5.30E-01
|
|
37
|
+
1.00E+05 6.10E-01
|
|
38
|
+
1.50E+05 8.90E-01
|
|
39
|
+
2.00E+05 1.20E+00
|
|
40
|
+
3.00E+05 1.80E+00
|
|
41
|
+
4.00E+05 2.38E+00
|
|
42
|
+
5.00E+05 2.93E+00
|
|
43
|
+
6.00E+05 3.44E+00
|
|
44
|
+
8.00E+05 4.38E+00
|
|
45
|
+
1.00E+06 5.20E+00
|
|
46
|
+
1.50E+06 6.90E+00
|
|
47
|
+
2.00E+06 8.60E+00
|
|
48
|
+
3.00E+06 1.11E+01
|
|
49
|
+
4.00E+06 1.34E+01
|
|
50
|
+
5.00E+06 1.55E+01
|
|
51
|
+
6.00E+06 1.76E+01
|
|
52
|
+
8.00E+06 2.16E+01
|
|
53
|
+
1.00E+07 2.56E+01
|
|
54
|
+
5.00E+07 2.56E+01
|
|
55
|
+
""",
|
|
56
|
+
'ICRP_neutron':
|
|
57
|
+
"""0.00 0.00
|
|
58
|
+
1.00E-03 3.09E+00
|
|
59
|
+
1.00E-02 3.55E+00
|
|
60
|
+
2.50E-02 4.00E+00
|
|
61
|
+
1.00E-01 5.20E+00
|
|
62
|
+
2.00E-01 5.87E+00
|
|
63
|
+
5.00E-01 6.59E+00
|
|
64
|
+
1.00E+00 7.03E+00
|
|
65
|
+
2.00E+00 7.39E+00
|
|
66
|
+
5.00E+00 7.71E+00
|
|
67
|
+
1.00E+01 7.82E+00
|
|
68
|
+
2.00E+01 7.84E+00
|
|
69
|
+
5.00E+01 7.82E+00
|
|
70
|
+
1.00E+02 7.79E+00
|
|
71
|
+
2.00E+02 7.73E+00
|
|
72
|
+
5.00E+02 7.54E+00
|
|
73
|
+
1.00E+03 7.54E+00
|
|
74
|
+
2.00E+03 7.61E+00
|
|
75
|
+
5.00E+03 7.97E+00
|
|
76
|
+
1.00E+04 9.11E+00
|
|
77
|
+
2.00E+04 1.22E+01
|
|
78
|
+
3.00E+04 1.57E+01
|
|
79
|
+
5.00E+04 2.30E+01
|
|
80
|
+
7.00E+04 3.06E+01
|
|
81
|
+
1.00E+05 4.19E+01
|
|
82
|
+
1.50E+05 6.06E+01
|
|
83
|
+
2.00E+05 7.88E+01
|
|
84
|
+
3.00E+05 1.14E+02
|
|
85
|
+
5.00E+05 1.77E+02
|
|
86
|
+
7.00E+05 2.32E+02
|
|
87
|
+
9.00E+05 2.79E+02
|
|
88
|
+
1.00E+06 3.01E+02
|
|
89
|
+
1.20E+06 3.30E+02
|
|
90
|
+
1.50E+06 3.65E+02
|
|
91
|
+
2.00E+06 4.07E+02
|
|
92
|
+
3.00E+06 4.58E+02
|
|
93
|
+
4.00E+06 4.83E+02
|
|
94
|
+
5.00E+06 4.94E+02
|
|
95
|
+
6.00E+06 4.98E+02
|
|
96
|
+
7.00E+06 4.99E+02
|
|
97
|
+
8.00E+06 4.99E+02
|
|
98
|
+
9.00E+06 5.00E+02
|
|
99
|
+
1.00E+07 5.00E+02
|
|
100
|
+
1.20E+07 4.99E+02
|
|
101
|
+
1.40E+07 4.95E+02
|
|
102
|
+
1.50E+07 4.93E+02
|
|
103
|
+
1.60E+07 4.90E+02
|
|
104
|
+
1.80E+07 4.84E+02
|
|
105
|
+
2.00E+07 4.77E+02
|
|
106
|
+
2.10E+07 4.74E+02
|
|
107
|
+
3.00E+07 4.53E+02
|
|
108
|
+
5.00E+07 4.33E+02
|
|
109
|
+
7.50E+07 4.39E+02
|
|
110
|
+
1.00E+08 4.44E+02
|
|
111
|
+
1.30E+08 4.46E+02
|
|
112
|
+
1.50E+08 4.46E+02
|
|
113
|
+
1.80E+08 4.47E+02
|
|
114
|
+
2.00E+08 4.48E+02
|
|
115
|
+
3.00E+08 4.73E+02
|
|
116
|
+
4.00E+08 5.15E+02
|
|
117
|
+
5.00E+08 5.33E+02
|
|
118
|
+
6.00E+08 5.69E+02
|
|
119
|
+
7.00E+08 6.25E+02
|
|
120
|
+
8.00E+08 6.38E+02
|
|
121
|
+
9.00E+08 6.45E+02
|
|
122
|
+
1.00E+09 6.63E+02
|
|
123
|
+
2.00E+09 7.69E+02
|
|
124
|
+
5.00E+09 1.04E+03
|
|
125
|
+
1.00E+10 1.39E+03
|
|
126
|
+
""",
|
|
127
|
+
'ICRP_photon':
|
|
128
|
+
"""0.00 0.00
|
|
129
|
+
5.00E+03 1.34E-02
|
|
130
|
+
6.00E+03 1.66E-02
|
|
131
|
+
7.00E+03 2.25E-02
|
|
132
|
+
8.00E+03 3.35E-02
|
|
133
|
+
9.00E+03 4.90E-02
|
|
134
|
+
1.00E+04 6.85E-02
|
|
135
|
+
1.20E+04 1.05E-01
|
|
136
|
+
1.30E+04 1.22E-01
|
|
137
|
+
1.50E+04 1.56E-01
|
|
138
|
+
1.70E+04 1.81E-01
|
|
139
|
+
2.00E+04 2.25E-01
|
|
140
|
+
2.50E+04 2.75E-01
|
|
141
|
+
3.00E+04 3.12E-01
|
|
142
|
+
4.00E+04 3.50E-01
|
|
143
|
+
5.00E+04 3.69E-01
|
|
144
|
+
6.00E+04 3.89E-01
|
|
145
|
+
7.00E+04 4.11E-01
|
|
146
|
+
8.00E+04 4.43E-01
|
|
147
|
+
1.00E+05 5.18E-01
|
|
148
|
+
1.50E+05 7.47E-01
|
|
149
|
+
2.00E+05 1.00E+00
|
|
150
|
+
3.00E+05 1.51E+00
|
|
151
|
+
4.00E+05 2.00E+00
|
|
152
|
+
5.00E+05 2.47E+00
|
|
153
|
+
5.11E+05 2.52E+00
|
|
154
|
+
6.00E+05 2.91E+00
|
|
155
|
+
6.62E+05 3.17E+00
|
|
156
|
+
8.00E+05 3.73E+00
|
|
157
|
+
1.00E+06 4.49E+00
|
|
158
|
+
1.12E+06 4.90E+00
|
|
159
|
+
1.33E+06 5.60E+00
|
|
160
|
+
1.50E+06 6.12E+00
|
|
161
|
+
2.00E+06 7.48E+00
|
|
162
|
+
3.00E+06 9.75E+00
|
|
163
|
+
4.00E+06 1.17E+01
|
|
164
|
+
5.00E+06 1.34E+01
|
|
165
|
+
6.00E+06 1.50E+01
|
|
166
|
+
6.13E+06 1.52E+01
|
|
167
|
+
8.00E+06 1.86E+01
|
|
168
|
+
1.00E+07 2.21E+01
|
|
169
|
+
1.50E+07 3.04E+01
|
|
170
|
+
2.00E+07 3.82E+01
|
|
171
|
+
3.00E+07 5.13E+01
|
|
172
|
+
4.00E+07 6.18E+01
|
|
173
|
+
5.00E+07 7.23E+01
|
|
174
|
+
6.00E+07 8.21E+01
|
|
175
|
+
8.00E+07 9.81E+01
|
|
176
|
+
1.00E+08 1.10E+02
|
|
177
|
+
1.50E+08 1.30E+02
|
|
178
|
+
2.00E+08 1.44E+02
|
|
179
|
+
3.00E+08 1.61E+02
|
|
180
|
+
4.00E+08 1.73E+02
|
|
181
|
+
5.00E+08 1.81E+02
|
|
182
|
+
6.00E+08 1.87E+02
|
|
183
|
+
8.00E+08 1.96E+02
|
|
184
|
+
1.00E+09 2.06E+02
|
|
185
|
+
1.50E+09 2.13E+02
|
|
186
|
+
2.00E+09 2.36E+02
|
|
187
|
+
3.00E+09 2.53E+02
|
|
188
|
+
4.00E+09 2.67E+02
|
|
189
|
+
5.00E+09 2.77E+02
|
|
190
|
+
6.00E+09 2.85E+02
|
|
191
|
+
8.00E+09 2.99E+02
|
|
192
|
+
1.00E+10 3.07E+02
|
|
193
|
+
"""
|
|
194
|
+
}
|
kdsource/api.py
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
"""Python module for creating and optimizing KDSource objects.
|
|
4
|
+
|
|
5
|
+
KDSource's are particle sources for Monte Carlo radiation transport
|
|
6
|
+
simulations. The full distribution and documentation can be found in the
|
|
7
|
+
project GitHub page:
|
|
8
|
+
|
|
9
|
+
https://github.com/KDSource/KDSource
|
|
10
|
+
|
|
11
|
+
A KDSource object is based on a particle list in MCPL format (see
|
|
12
|
+
https://mctools.github.io/mcpl/), on which a Kernel Density Estimation
|
|
13
|
+
(KDE) is applied, using KDEpy library (see
|
|
14
|
+
https://github.com/tommyod/KDEpy).
|
|
15
|
+
|
|
16
|
+
With kdsource Python library you can create, optimize, and export
|
|
17
|
+
KDSource objects as XML files. These files can be later used as
|
|
18
|
+
distributional sources in other Monte Carlo simulations, using the tools
|
|
19
|
+
available in the full distribution.
|
|
20
|
+
|
|
21
|
+
If you use KDSource tools in your work, please add the following
|
|
22
|
+
reference:
|
|
23
|
+
|
|
24
|
+
Abbate, O. I., Schmidt, N. S., Prieto, Z. M., Robledo, J. I.,
|
|
25
|
+
Dawidowski, J., Márquez, A. A., & Márquez Damián, J. I. KDSource,
|
|
26
|
+
a tool for the generation of Monte Carlo particle sources using
|
|
27
|
+
kernel density estimation [Computer software].
|
|
28
|
+
https://github.com/KDSource/KDSource
|
|
29
|
+
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
__version__ = "0.2.0"
|
|
33
|
+
versionint = int('2000')
|
|
34
|
+
version = ( int('0'),
|
|
35
|
+
int('2'),
|
|
36
|
+
int('0') )
|
|
37
|
+
__author__ = "KDSource"
|
|
38
|
+
|
|
39
|
+
#Convenience module with ~all imports (leaving __init__.py empty as per
|
|
40
|
+
#best-practice, and to not make e.g. CLI scripts fail due to missing un-needed
|
|
41
|
+
#dependency)
|
|
42
|
+
from . import geom #noqa F401
|
|
43
|
+
from . import kde #noqa F401
|
|
44
|
+
from . import plist #noqa F401
|
|
45
|
+
from .geom import Geometry, Metric #noqa F401
|
|
46
|
+
from .kde import bw_silv #noqa F401
|
|
47
|
+
from .kdsource import KDSource, load #noqa F401
|
|
48
|
+
from .plist import PList, appendssv, convert2mcpl, join2mcpl, savessv #noqa F401
|
|
49
|
+
from .writemcpl import write_mcpl #noqa F401
|
|
50
|
+
from .resample import resample_to_mcpl #noqa F401
|
kdsource/config.py
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import pathlib as _p
|
|
2
|
+
_datadir = _p.Path(__file__).parent.joinpath('data').absolute()
|
|
3
|
+
config_items = [
|
|
4
|
+
'version',
|
|
5
|
+
'intversion',
|
|
6
|
+
'includedir',
|
|
7
|
+
'libdir',
|
|
8
|
+
'libpath',
|
|
9
|
+
'libname',
|
|
10
|
+
'shlibdir',
|
|
11
|
+
'shlibpath',
|
|
12
|
+
'shlibname',
|
|
13
|
+
'buildflags',
|
|
14
|
+
]
|
|
15
|
+
|
|
16
|
+
def summary():
|
|
17
|
+
"""Print summary of all config items"""
|
|
18
|
+
print("KDSource v%s with configuration:"%config('version'))
|
|
19
|
+
print()
|
|
20
|
+
maxlen = max(len(item) for item in config_items)
|
|
21
|
+
for item in config_items:
|
|
22
|
+
print(' %s : %s'%(item.rjust(maxlen),config(item)))
|
|
23
|
+
|
|
24
|
+
_config_cache={}
|
|
25
|
+
def config(item):
|
|
26
|
+
"""Return configuration item (available are those in the config_item list).
|
|
27
|
+
"""
|
|
28
|
+
c = _config_cache.get(item)
|
|
29
|
+
if c is not None:
|
|
30
|
+
return c
|
|
31
|
+
c = _config_deduce(item)
|
|
32
|
+
_config_cache[item] = c
|
|
33
|
+
return c
|
|
34
|
+
|
|
35
|
+
def _config_deduce(item):
|
|
36
|
+
if item not in config_items:
|
|
37
|
+
raise RuntimeError(f"unknown config item: {item}")
|
|
38
|
+
if 'lib' not in item:
|
|
39
|
+
if item=='includedir':
|
|
40
|
+
return _datadir.joinpath('include')
|
|
41
|
+
if item=='buildflags':
|
|
42
|
+
import platform
|
|
43
|
+
if platform.system()=='Windows':
|
|
44
|
+
return '"/I%s" "%s"'%(config('includedir'),config('libpath'))
|
|
45
|
+
import shlex
|
|
46
|
+
return shlex.join(
|
|
47
|
+
shlex.quote(e)
|
|
48
|
+
for e in [ "-Wl,-rpath,%s"%config('libdir'),
|
|
49
|
+
"-Wl,%s"%config('libpath'),
|
|
50
|
+
"-I%s"%config('includedir') ]
|
|
51
|
+
)
|
|
52
|
+
if item=='intversion':
|
|
53
|
+
return "2000"
|
|
54
|
+
if item=='version':
|
|
55
|
+
return "0.2.0"
|
|
56
|
+
|
|
57
|
+
winsuffix = '.lib'
|
|
58
|
+
look_in_scripts_for_dll = False
|
|
59
|
+
if item.startswith('sh'):
|
|
60
|
+
winsuffix = '.dll'
|
|
61
|
+
item = item[2:]
|
|
62
|
+
#The next is only True on Windows in python installations:
|
|
63
|
+
look_in_scripts_for_dll = bool('1')
|
|
64
|
+
|
|
65
|
+
if look_in_scripts_for_dll:
|
|
66
|
+
p = _win_find_dll()
|
|
67
|
+
if item=='libdir':
|
|
68
|
+
return p.parent
|
|
69
|
+
return p.name if item=='libname' else p
|
|
70
|
+
|
|
71
|
+
libdir = _datadir.joinpath('lib')
|
|
72
|
+
|
|
73
|
+
if item=='libdir':
|
|
74
|
+
return libdir
|
|
75
|
+
|
|
76
|
+
libs = list( e for e in libdir.glob('*') if 'kdsource' in e.name.lower() )
|
|
77
|
+
libs_win = [ e for e in libs if e.name.lower().endswith(winsuffix) ]
|
|
78
|
+
libs_other = [ e for e in libs if not e.name.lower().endswith(winsuffix) ]
|
|
79
|
+
libs = libs_win or libs_other
|
|
80
|
+
|
|
81
|
+
if not libs:
|
|
82
|
+
raise RuntimeError('Inconsistent installation of KDSource'
|
|
83
|
+
' (could not find shared lib)')
|
|
84
|
+
if len(libs)!=1:
|
|
85
|
+
s = ' '.join(e.name for e in libs)
|
|
86
|
+
raise RuntimeError('Inconsistent installation of KDSource (multiple'
|
|
87
|
+
f' libs: {s})')
|
|
88
|
+
assert len(libs)==1
|
|
89
|
+
return libs[0].name if item=='libname' else libs[0]
|
|
90
|
+
|
|
91
|
+
__cache_windll = [None]
|
|
92
|
+
def _win_find_dll():
|
|
93
|
+
#Windows. The DLL is in the scripts directory (to be in %PATH%). To be safe
|
|
94
|
+
#we look not only in the default scheme, but also in a few other preferred
|
|
95
|
+
#schemes. The sysconfig usage below assumes python 3.10 or later:
|
|
96
|
+
if __cache_windll[0] is not None:
|
|
97
|
+
return __cache_windll[0]
|
|
98
|
+
|
|
99
|
+
import sysconfig
|
|
100
|
+
import pathlib
|
|
101
|
+
schemes = [ sysconfig.get_default_scheme() ]
|
|
102
|
+
for scheme_key in ['prefix','home','user']:
|
|
103
|
+
scheme = sysconfig.get_preferred_scheme(scheme_key)
|
|
104
|
+
if scheme not in schemes:
|
|
105
|
+
schemes.append(scheme)
|
|
106
|
+
ln, ln2, res = 'kdsource.dll', 'kdsource.DLL', None
|
|
107
|
+
for scheme in schemes:
|
|
108
|
+
p = pathlib.Path( sysconfig.get_path('scripts',scheme) )
|
|
109
|
+
p1 = p.joinpath(ln)
|
|
110
|
+
if p1.is_file():
|
|
111
|
+
res = p1
|
|
112
|
+
break
|
|
113
|
+
p2 = p.joinpath(ln2)
|
|
114
|
+
if p2.is_file():
|
|
115
|
+
res = p2
|
|
116
|
+
break
|
|
117
|
+
if res is None:
|
|
118
|
+
raise RuntimeError('Unable to locate shared library (expected '
|
|
119
|
+
f'{ln} in Python site scripts directory)')
|
|
120
|
+
__cache_windll[0] = res.absolute().resolve()
|
|
121
|
+
return __cache_windll[0]
|