Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Identify TENDL 2017 files for GROUPR processing and data extraction #68

Merged
merged 15 commits into from
Aug 6, 2024
40 changes: 26 additions & 14 deletions src/DataLib/fendl32B_retrofit/process_fendl3.2.py
Original file line number Diff line number Diff line change
@@ -1,32 +1,44 @@
# Import packages
import shutil
import reaction_data as rxd
import tendl_processing as tp
import groupr_tools
from pandas import DataFrame

def main():
"""
Main method when run as a command line script.
"""

TAPE20 = 'tape20'
TAPE21 = 'tape21'

mt_dict = rxd.process_mt_data(rxd.load_mt_table('mt_table.csv'))

endf_path = 'tape20'
pendf_path = 'tape21'
cumulative_data = []
for isotope, file_properties in tp.search_for_files().items():
element = file_properties['Element']
A = file_properties['Mass Number']
endf_path, pendf_path = file_properties['File Paths']
shutil.copy(endf_path, TAPE20)
shutil.copy(pendf_path, TAPE21)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should work from Pathlib (trying to reduce number of dependencies, even if they're built in; I also think it's a more modern solution???):

Suggested change
shutil.copy(endf_path, TAPE20)
shutil.copy(pendf_path, TAPE21)
Path(TAPE20).write_bytes(endf_path.read_bytes())
Path(TAPE21).write_bytes(pendf_path.read_bytes())


material_id, MTs, endftk_file_obj = tp.extract_endf_specs(endf_path)
MTs = list(set(MTs).intersection(mt_dict.keys()))
njoy_input = groupr_tools.fill_input_template(material_id, MTs, 'Fe', 56, mt_dict)
groupr_tools.write_njoy_input_file(njoy_input)
gendf_path = groupr_tools.run_njoy('Fe', 56, material_id)
material_id, MTs, endftk_file_obj = tp.extract_endf_specs(TAPE20)
MTs = set(MTs).intersection(mt_dict.keys())
njoy_input = groupr_tools.fill_input_template(material_id, MTs,
element, A, mt_dict)
groupr_tools.write_njoy_input_file(njoy_input)
gendf_path = groupr_tools.run_njoy(element, A, material_id)

pKZA = tp.extract_gendf_pkza(gendf_path)
# Extract MT values again from GENDF file as there may be some difference
# from the original MT values in the ENDF/PENDF files
material_id, MTs, endftk_file_obj = tp.extract_endf_specs(gendf_path)
gendf_data = tp.iterate_MTs(MTs, endftk_file_obj, mt_dict, pKZA)
gendf_data.to_csv('gendf_data.csv')
groupr_tools.cleanup_njoy_files()
pKZA = tp.extract_gendf_pkza(gendf_path)
# Extract MT values again from GENDF file as there may be some
# difference from the original MT values in the ENDF/PENDF files
material_id, MTs, endftk_file_obj = tp.extract_endf_specs(gendf_path)
gendf_data = tp.iterate_MTs(MTs, endftk_file_obj, mt_dict, pKZA)
cumulative_data.extend(gendf_data)
groupr_tools.cleanup_njoy_files()

DataFrame(cumulative_data).to_csv('cumulative_gendf_data.csv')

if __name__ == '__main__':
main()
98 changes: 73 additions & 25 deletions src/DataLib/fendl32B_retrofit/tendl_processing.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,64 @@
# Import packages
import ENDFtk
import pandas as pd
from pathlib import Path

def get_isotope(stem):
"""
Extract the element name and mass number from a given filename.

Arguments:
stem (str): Stem of a an ENDF (TENDL) and/or PENDF file, formatted
as f'{element}{mass_number}.ext'
Returns:
element (str): Chemical symbol of the isotope whose data is contained
in the file.
A (str): Mass number of the isotope, potentially including the letter
"m" at the end if the isotope is in a metastable state.
"""

for i, char in enumerate(stem):
if char.isdigit():
break

element = stem[:i]
A = stem[i:]

return element, A

def search_for_files(dir = '.'):
"""
Search through a directory for all pairs of ENDF (TENDL) and PENDF files
that have matching stems. If so, save the paths and the isotopic
information to a dictionary.

Arguments:
directory (str, optional): Path to the directory in which to search
for ENDF and PENDF files.
Defaults to the present working directory (".").
Returns:
file_info (dict): Dictionary containing the chemical symbol, mass
number, and paths to the ENDF and PENDF files for a given isotope.
The dictionary is formatted as such:
{f'{element}{mass_number}' :
{'Element'} : Isotope's chemical symbol,
{'Mass Number'} : Isotope's mass number,
{'File Paths'} : (endf_path, pendf_path)
}
"""

dir = Path(dir)

file_info = {}
for file in (p for p in dir.glob('*') if p.suffix in {'.tendl', '.endf'}):
if file.is_file() and file.with_suffix('.pendf').is_file():
element, A = get_isotope(file.stem)
file_info[f'{element}{A}'] = {
'Element' : element,
'Mass Number' : A,
'File Paths' : (file, file.with_suffix('.pendf'))
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was thinking that the glob could allow you to be more selective about which files you are even looking for:

Suggested change
for file in (p for p in dir.glob('*') if p.suffix in {'.tendl', '.endf'}):
if file.is_file() and file.with_suffix('.pendf').is_file():
element, A = get_isotope(file.stem)
file_info[f'{element}{A}'] = {
'Element' : element,
'Mass Number' : A,
'File Paths' : (file, file.with_suffix('.pendf'))
}
for suffix in ['tendl', 'endf']:
for file in dir.glob(f'*.{suffix}'):
if file.with_suffix('.pendf').is_file():
element, A = get_isotope(file.stem)
file_info[f'{element}{A}'] = {
'Element' : element,
'Mass Number' : A,
'File Paths' : (file, file.with_suffix('.pendf'))
}


return file_info

def extract_endf_specs(path):
"""
Expand Down Expand Up @@ -99,33 +157,23 @@ def iterate_MTs(MTs, file_obj, mt_dict, pKZA):
pKZA (int): Parent KZA identifier.

Returns:
gendf_data (pandas.core.frame.DataFrame): Pandas DataFrame containing
parent KZA values, daughter KZA values, emitted particles,
counts of the number of non-zero groups in the Vitamin-J groupwise
structure, and the cross-section values for those groups.
gendf_data (list of dict): List of dictionaries containing parent KZA
daughter KZA values, emitted particles, counts of the number of
non-zero groups in the Vitamin-J groupwise structure, and the
cross-section values for those groups, organized by MT number.
"""

cross_sections_by_MT = []
emitted_particles_list = []
dKZAs = []
groups = []

gendf_data = []
for MT in MTs:
sigma_list = extract_cross_sections(file_obj, MT)
dKZA = pKZA + mt_dict[MT]['delKZA']
emitted_particles = mt_dict[MT]['Emitted Particles']
cross_sections_by_MT.append(sigma_list)

dKZAs.append(dKZA)
emitted_particles_list.append(emitted_particles)
groups.append(len(sigma_list))

gendf_data = pd.DataFrame({
'Parent KZA' : [pKZA] * len(dKZAs),
'Daughter KZA' : dKZAs,
'Emitted Particles' : emitted_particles_list,
'Non-Zero Groups' : groups,
'Cross Sections' : cross_sections_by_MT
})
gendf_data.append(
{
'Parent KZA' : pKZA,
'Daughter KZA' : pKZA + mt_dict[MT]['delKZA'],
'Emitted Particles' : mt_dict[MT]['Emitted Particles'],
'Non-Zero Groups' : len(sigma_list),
'Cross Sections' : sigma_list
}
)

return gendf_data