Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
Luca Fiorito committed Oct 18, 2021
1 parent cdbfcfc commit 39326fb
Show file tree
Hide file tree
Showing 2 changed files with 152 additions and 56 deletions.
194 changes: 145 additions & 49 deletions sandy/core/endf6.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import io
import shutil
import os
from functools import reduce
from tempfile import TemporaryDirectory
import logging
from urllib.request import urlopen, Request
Expand All @@ -29,7 +30,7 @@
URL_N_JEFF_40T0_NEA,
URL_N_ENDFB_80_IAEA,
URL_N_JENDL_40U_IAEA,
URL_NFPY_ENDFB_80_IAEA,
URL_NFPY_ENDFB_80_IAEA,
NFPY_FILES_ENDFB_80_IAEA,
URL_NFPY_ENDFB_71_IAEA,
NFPY_FILES_ENDFB_71_IAEA,
Expand Down Expand Up @@ -79,7 +80,7 @@ def get_endf6_file(library, kind, zam, to_file=False):
for decay:
* `'endfb_71'`
* `'jeff_33'`
* `'endfb_80'`
* `'endfb_80'`
kind : `str`
nuclear data type:
* `xs` is a standard neutron-induced nuclear data file
Expand Down Expand Up @@ -407,14 +408,6 @@ def from_zipurl(cls, filename, rooturl):
tape = cls.from_file(tmpfile)
return tape

# @classmethod
# def from_url(cls, url):
# # set a known browser user agent to ensure access
# req = Request(url, headers={'User-Agent': 'Mozilla/5.0'},)
# with urlopen(req) as f:
# text = f.read().decode('utf-8')
# return cls.from_text(text)

@classmethod
def from_file(cls, file):
"""
Expand Down Expand Up @@ -553,7 +546,7 @@ def foo(x):
)
return df

def add_section(self, mat, mf, mt, text, inplace=False):
def add_section(self, mat, mf, mt, text):
"""
Given MAT, MF and MT add/replace the corresponding section in the
`Endf6.data`.
Expand All @@ -566,8 +559,6 @@ def add_section(self, mat, mf, mt, text, inplace=False):
MF number
mt : `int`
MT number
inplace : `bool`, optional, default is `False`
flag to operate **inplace**
Returns
-------
Expand All @@ -582,32 +573,20 @@ def add_section(self, mat, mf, mt, text, inplace=False):
9437 3 102 lorem ipsum
9999 1 1 dolor sit amet
dtype: object
>>> tape.add_section(9437, 3, 102, "new text", inplace=True)
>>> tape
MAT MF MT
9437 3 102 new text
dtype: object
"""
d = self.data.copy()
key = (mat, mf, mt)
d[key] = text
if inplace:
self.data = d
else:
return self.__class__(d)
return self.__class__(d)

def add_sections(self, sections, inplace=False):
def add_sections(self, sections):
d = self.data.copy()
for (mat, mf, mt), text in sections.items():
key = (mat, mf, mt)
d[key] = text
if inplace:
self.data = d
else:
return self.__class__(d)
return self.__class__(d)

def delete_section(self, mat, mf, mt, inplace=False, raise_error=True):
def delete_section(self, mat, mf, mt, raise_error=True):
"""
Given MAT, MF and MT delete the corresponding section from the
`Endf6.data`.
Expand All @@ -620,8 +599,6 @@ def delete_section(self, mat, mf, mt, inplace=False, raise_error=True):
MF number
mt : `int`
MT number
inplace : `bool`, optional, default is `False`
flag to operate **inplace**
Returns
-------
Expand All @@ -646,41 +623,160 @@ def delete_section(self, mat, mf, mt, inplace=False, raise_error=True):
2 1.001000+3 9.991673-1 0 0 ...
102 1.001000+3 9.991673-1 0 0 ...
dtype: object
This method can also work **inplace**.
>>> tape.delete_section(125, 3, 102, inplace=True)
>>> assert tape.data == new.data
"""
d = self.data.copy()
key = (mat, mf, mt)
if key not in d and raise_error is False:
pass
else:
del d[key]
if inplace:
self.data = d
else:
return self.__class__(d)
return self.__class__(d)

def delete_sections(self, sections, inplace=False, raise_error=True):
def delete_sections(self, sections, raise_error=True):
d = self.data.copy()
for mat, mf, mt in sections:
key = (mat, mf, mt)
if key not in d and raise_error is False:
pass
else:
del d[key]
if inplace:
self.data = d
else:
return self.__class__(d)
return self.__class__(d)

def merge(self, *iterable):
"""
Given a single `sandy.Endf6` object or an iterable of `sandy.Endf6`
objects as keyword arguments, add their sections to a copy of the
`self` instance and return a new `sandy.Endf6` object.
The new `sandy.Endf6` object contains all MAT/MF/MT sections in `self`
and in the passed arguments.
Parameters
----------
iterable : `sandy.Endf6` or iterable of `sandy.Endf6` objects
The ENDF6 files that will be merged to `self`.
Returns
-------
merged : TYPE
a ENDF6 file containing the MAT/MF/MT sections of `self` and of
the passed ENDF6 files.
Notes
-----
.. note:: if any section (MAT/MF/MT) already present in the orginal
ENDF6 tape also appears in any tape that is being merged,
then the original ENDF6 section will be overwritten.
Examples
--------
Merge two files.
>>> h1 = sandy.get_endf6_file("jeff_33", 'xs', 10010)
>>> h2 = sandy.get_endf6_file("endfb_71", 'xs', 10020)
>>> h1.merge(h2)
MAT MF MT
125 1 451 1.001000+3 9.991673-1 0 0 ...
2 151 1.001000+3 9.991673-1 0 0 ...
3 1 1.001000+3 9.991673-1 0 0 ...
2 1.001000+3 9.991673-1 0 0 ...
102 1.001000+3 9.991673-1 0 0 ...
4 2 1.001000+3 9.991673-1 0 1 ...
6 102 1.001000+3 9.991673-1 0 2 ...
33 1 1.001000+3 9.991673-1 0 0 ...
2 1.001000+3 9.991673-1 0 0 ...
102 1.001000+3 9.991673-1 0 0 ...
128 1 451 1.002000+3 1.996800+0 0 0 ...
2 151 1.002000+3 1.996800+0 0 0 ...
3 1 1.002000+3 1.996800+0 0 0 ...
2 1.002000+3 1.996800+0 0 0 ...
3 1.002000+3 1.996800+0 0 0 ...
16 1.002000+3 1.996800+0 0 0 ...
102 1.002000+3 1.996800+0 0 0 ...
4 2 1.002000+3 1.996800+0 0 2 ...
6 16 1.002000+3 1.996800+0 0 1 ...
8 102 1.002000+3 1.996800+0 0 0 ...
9 102 1.002000+3 1.996800+0 0 0 ...
12 102 1.002000+3 1.996800+0 1 0 ...
14 102 1.002000+3 1.996800+0 1 0 ...
33 1 1.002000+3 1.996800+0 0 0 ...
2 1.002000+3 1.996800+0 0 0 ...
16 1.002000+3 1.996800+0 0 0 ...
102 1.002000+3 1.996800+0 0 0 ...
dtype: object
Merge three files from different libraries.
>>> h3 = sandy.get_endf6_file("endfb_71", 'xs', 10030)
>>> h1.merge(h2, h3)
MAT MF MT
125 1 451 1.001000+3 9.991673-1 0 0 ...
2 151 1.001000+3 9.991673-1 0 0 ...
3 1 1.001000+3 9.991673-1 0 0 ...
2 1.001000+3 9.991673-1 0 0 ...
102 1.001000+3 9.991673-1 0 0 ...
4 2 1.001000+3 9.991673-1 0 1 ...
6 102 1.001000+3 9.991673-1 0 2 ...
33 1 1.001000+3 9.991673-1 0 0 ...
2 1.001000+3 9.991673-1 0 0 ...
102 1.001000+3 9.991673-1 0 0 ...
128 1 451 1.002000+3 1.996800+0 0 0 ...
2 151 1.002000+3 1.996800+0 0 0 ...
3 1 1.002000+3 1.996800+0 0 0 ...
2 1.002000+3 1.996800+0 0 0 ...
3 1.002000+3 1.996800+0 0 0 ...
16 1.002000+3 1.996800+0 0 0 ...
102 1.002000+3 1.996800+0 0 0 ...
4 2 1.002000+3 1.996800+0 0 2 ...
6 16 1.002000+3 1.996800+0 0 1 ...
8 102 1.002000+3 1.996800+0 0 0 ...
9 102 1.002000+3 1.996800+0 0 0 ...
12 102 1.002000+3 1.996800+0 1 0 ...
14 102 1.002000+3 1.996800+0 1 0 ...
33 1 1.002000+3 1.996800+0 0 0 ...
2 1.002000+3 1.996800+0 0 0 ...
16 1.002000+3 1.996800+0 0 0 ...
102 1.002000+3 1.996800+0 0 0 ...
131 1 451 1.003000+3 2.989596+0 0 0 ...
2 151 1.003000+3 2.989596+0 0 0 ...
3 1 1.003000+3 2.989596+0 0 0 ...
2 1.003000+3 2.989596+0 0 0 ...
16 1.003000+3 2.989596+0 0 0 ...
4 2 1.003000+3 2.989596+0 0 1 ...
16 1.003000+3 2.989596+0 0 2 ...
5 16 1.003000+3 2.989596+0 0 0 ...
dtype: object
Merge two evaluations for the same nuclide.
>>> h2_2 = sandy.get_endf6_file("jeff_32", 'xs', 10020)
>>> h2.merge(h2_2)
MAT MF MT
128 1 451 1.002000+3 1.995712+0 0 0 ...
2 151 1.002000+3 1.995712+0 0 0 ...
3 1 1.002000+3 1.995712+0 0 0 ...
2 1.002000+3 1.995712+0 0 0 ...
3 1.002000+3 1.995712+0 0 0 ...
16 1.002000+3 1.995712+0 0 0 ...
102 1.002000+3 1.995712+0 0 0 ...
4 2 1.002000+3 1.995712+0 0 1 ...
6 16 1.002000+3 1.995712+0 0 1 ...
8 102 1.002000+3 1.996800+0 0 0 ...
9 102 1.002000+3 1.996800+0 0 0 ...
12 102 1.002000+3 1.995712+0 1 0 ...
14 102 1.002000+3 1.995712+0 1 0 ...
33 1 1.002000+3 1.996800+0 0 0 ...
2 1.002000+3 1.996800+0 0 0 ...
16 1.002000+3 1.996800+0 0 0 ...
102 1.002000+3 1.996800+0 0 0 ...
dtype: object
"""
tape = reduce(lambda x, y: x.add_sections(y.data), iterable)
merged = self.add_sections(tape.data)
return merged

def filter_by(self,
listmat=range(1,10000),
listmf=range(1,10000),
listmt=range(1,10000)):
listmat=range(1, 10000),
listmf=range(1, 10000),
listmt=range(1, 10000)):
"""Filter dataframe based on MAT, MF, MT lists.
Parameters
----------
listmat : `list` or `None`
Expand All @@ -689,7 +785,7 @@ def filter_by(self,
list of requested MF values (default is `None`: use all MF)
listmt : `list` or `None`
list of requested MT values (default is `None`: use all MT)
Returns
-------
`sandy.formats.endf6.BaseFile` or derived instance
Expand Down
14 changes: 7 additions & 7 deletions sandy/core/xs.py
Original file line number Diff line number Diff line change
Expand Up @@ -310,15 +310,15 @@ def from_endf6(cls, endf6):
for mat, mf, mt in tape.data:
sec = tape.read_section(mat, mf, mt)
if sec['INT'] != [2]:
logging.warning("skip MAT{mat}/MF{mf}/MT{mt} "
f"because interpolation schme is not lin-lin")
logging.warning(f"skip MAT{mat}/MF{mf}/MT{mt} "
"because interpolation schme is not lin-lin")
continue
xs = pd.Series(sec["XS"], index=sec["E"], name=(mat, mt)) \
.rename_axis("E") \
.to_frame()
mask_duplicates = xs.index.duplicated(keep=keep)
for energy in xs.index[mask_duplicates]:
logging.warning(f"found duplicate energy for "
logging.warning("found duplicate energy for "
f"MAT{mat}/MF{mf}/MT{mt} "
f"at {energy:.5e} MeV, keep only {keep} value")
xs = xs[~mask_duplicates]
Expand All @@ -330,18 +330,18 @@ def from_endf6(cls, endf6):
sec = tape.read_section(mat, mf, mt)
if sec["LNU"] != 2:
logging.warning(f"skip MAT{mat}/MF{mf}/MT{mt} "
f"because not tabulated")
"because not tabulated")
continue
if sec['INT'] != [2]:
logging.warning("skip MAT{mat}/MF{mf}/MT{mt} "
f"because interpolation schme is not lin-lin")
logging.warning(f"skip MAT{mat}/MF{mf}/MT{mt} "
"because interpolation schme is not lin-lin")
continue
xs = pd.Series(sec["NU"], index=sec["E"], name=(mat, mt)) \
.rename_axis("E") \
.to_frame()
mask_duplicates = xs.index.duplicated(keep=keep)
for energy in xs.index[mask_duplicates]:
logging.warning(f"found duplicate energy for "
logging.warning("found duplicate energy for "
f"MAT{mat}/MF{mf}/MT{mt} "
f"at {energy:.5e} MeV, keep only {keep} value")
xs = xs[~mask_duplicates]
Expand Down

0 comments on commit 39326fb

Please sign in to comment.