-
Notifications
You must be signed in to change notification settings - Fork 0
Dump sources #46
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
Dump sources #46
Changes from 8 commits
6e893d2
9e8c7a4
6f7af2f
543a2e6
c031862
c6f3ead
4565b49
f069b6f
b99d04a
51c00fc
b5c05a6
43ecbc6
77ef8a5
e60ad1a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,10 +1,10 @@ | ||
| import logging | ||
| import os | ||
| import sys | ||
| from importlib.resources import as_file, files | ||
| from math import pi | ||
| from pathlib import Path | ||
|
|
||
| from importlib.resources import files, as_file | ||
| import logging | ||
| import matplotlib.pyplot as plt | ||
| import numpy as np | ||
| import pyevtk | ||
|
|
@@ -102,7 +102,6 @@ def dose_from_line_source(dose, x1, y1, z1, x2, y2, z2, x, y, z): | |
| def is_within_bounds( | ||
| x1, y1, z1, flux_grid_file, stl_files_path=None, x2=None, y2=None, z2=None | ||
| ): | ||
|
|
||
| # If a path to the STL files is provided, use it | ||
| if stl_files_path is not None: | ||
| folder_path = Path(stl_files_path) | ||
|
|
@@ -178,7 +177,6 @@ def write_vtk_file( | |
| z2=None, | ||
| output_all_vtr=False, | ||
| ): | ||
|
|
||
| # Get the bounds in which to make the plot | ||
| plot_bounds = is_within_bounds( | ||
| x1, y1, z1, flux_grid_file, stl_files_path, x2, y2, z2 | ||
|
|
@@ -227,28 +225,40 @@ def write_vtk_file( | |
| ) | ||
| dose_array[i, j, k] = dose_point | ||
|
|
||
| # Create a 3D numpy array filled with the dose values based on 1/r^2 | ||
| # Create a 3D numpy array filled with the dose values based on 1/r^2 ( original bottom-left point source model) | ||
| else: | ||
| for i in range(len(x) - 1): | ||
| for j in range(len(y) - 1): | ||
| for k in range(len(z) - 1): | ||
| distance = np.sqrt( | ||
| (x[i] - x1) ** 2 + (y[j] - y1) ** 2 + (z[k] - z1) ** 2 | ||
| ) | ||
| ## get midpoints | ||
| # x_mid = (x[1:] + x[:-1]) / 2 | ||
| # y_mid = (y[1:] + y[:-1]) / 2 | ||
| # z_mid = (z[1:] + z[:-1]) / 2 | ||
| # for i in range(len(x_mid)): | ||
| # for j in range(len(y_mid)): | ||
| # for k in range(len(z_mid)): | ||
| # distance = np.sqrt( | ||
| # (x_mid[i] - x1) ** 2 + (y_mid[j] - y1) ** 2 + (z_mid[k] - z1) ** 2 | ||
| # ) | ||
| # Avoid division by zero | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think computing the values in the center of the voxel is more correct than computing it in one of the vertex and then shift it in the center
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If changing to middle point than the point value a 0 distance should be still divided by a distance value and not just be equal to "dose[0]" has it is now. I would suggest leave it like this; if an .stl file is not provided, I do not think 25 cm shift impact significantly, especially at several meters distances.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Implemented. Please note that the in case of distance==0 the dose value will be divided by 4*pi. |
||
| if distance == 0: | ||
| dose_array[i, j, k] = dose[0] | ||
| print("Dose at source point is:", dose[0]) | ||
|
||
| else: | ||
| dose_array[i, j, k] = dose[0] / (4 * pi * distance**2) | ||
|
|
||
| # Get the indices of the max value | ||
| indices = np.unravel_index(np.argmax(dose_array, axis=None), dose_array.shape) | ||
|
|
||
| # Get the coordinates of the max value | ||
| x_max = x[indices[0]] | ||
| y_max = y[indices[1]] | ||
| z_max = z[indices[2]] | ||
|
|
||
| # print( | ||
| # f"Max dose value: {dose_array[indices]} at coordinates: ({x_max}, {y_max}, {z_max})" | ||
| # ) | ||
| # Create the output directory if it doesn't exist | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This can probably be deleted and not just commented out |
||
| os.makedirs("output", exist_ok=True) | ||
|
|
||
|
|
@@ -265,7 +275,6 @@ def write_vtk_file( | |
|
|
||
|
|
||
| def plot_slice(dose_array, x, y, z, slice_axis, slice_location, plot_bounds): | ||
|
|
||
| # Map axis names to indices | ||
| axis_dict = {"x": 0, "y": 1, "z": 2} | ||
|
|
||
|
|
@@ -352,8 +361,9 @@ def format_func(value, tick_number): | |
| # Loop over each solid in the stl file and plot the slice | ||
| for solid in stl.solids: | ||
| slice = solid.slice(plane=slice_axis, intercept=slice_location) | ||
| pairs = getattr(slice, axis_pairs[slice_axis][0] + "_pairs"), getattr( | ||
| slice, axis_pairs[slice_axis][1] + "_pairs" | ||
| pairs = ( | ||
| getattr(slice, axis_pairs[slice_axis][0] + "_pairs"), | ||
| getattr(slice, axis_pairs[slice_axis][1] + "_pairs"), | ||
| ) | ||
| for pair in zip(*pairs): | ||
| ax.plot(*pair, color="black", linewidth=1) | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,30 +1,32 @@ | ||
| import logging | ||
| from jsonargparse import Namespace | ||
| import csv | ||
| import datetime | ||
| import json | ||
| import numpy as np | ||
| import logging | ||
| import os | ||
| from importlib.resources import files, as_file | ||
| from importlib.resources import as_file, files | ||
|
|
||
| import numpy as np | ||
| import pandas as pd | ||
| from jsonargparse import Namespace | ||
|
|
||
| from f4epurity.decay_chain_calc import calculate_total_activity | ||
| from f4epurity.collapse import collapse_flux, extract_xs | ||
| from f4epurity.dose import convert_to_dose, write_vtk_file, plot_slice | ||
| from f4epurity.decay_chain_calc import calculate_total_activity | ||
| from f4epurity.dose import convert_to_dose, plot_slice, write_vtk_file | ||
| from f4epurity.maintenance import ( | ||
| dose_within_workstation, | ||
| get_dose_at_workstation, | ||
| read_maintenance_locations, | ||
| ) | ||
| from f4epurity.parsing import parse_arguments, parse_isotopes_activities_file | ||
| from f4epurity.psource import GlobalPointSource, PointSource | ||
| from f4epurity.reaction_rate import calculate_reaction_rate | ||
| from f4epurity.utilities import ( | ||
| calculate_number_of_atoms, | ||
| get_isotopes, | ||
| sum_vtr_files, | ||
| normalise_nuclide_name, | ||
| get_reactions_from_file, | ||
| normalise_nuclide_name, | ||
| sum_vtr_files, | ||
| ) | ||
| from f4epurity.parsing import parse_arguments, parse_isotopes_activities_file | ||
|
|
||
| F4Epurity_TITLE = """ | ||
| _____ _ _ _____ _ _ | ||
|
|
@@ -76,7 +78,14 @@ def calculate_dose_for_source( | |
| x2: np.ndarray = None, | ||
| y2: np.ndarray = None, | ||
| z2: np.ndarray = None, | ||
| ) -> tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray, list[float]]: | ||
| ) -> tuple[ | ||
| np.ndarray, | ||
| np.ndarray, | ||
| np.ndarray, | ||
| np.ndarray, | ||
| list[float], | ||
| dict[str, list[np.ndarray]], | ||
| ]: | ||
| """Calculate the dose for a given source | ||
|
|
||
| Parameters | ||
|
|
@@ -141,7 +150,6 @@ def calculate_dose_for_source( | |
| sigma_eff, flux_spectrum = collapse_flux( | ||
| xs_values, args.input_flux, x1, y1, z1, x2, y2, z2 | ||
| ) | ||
|
|
||
| # Calculate the reaction rate based on the flux and effective cross section | ||
| reaction_rate = calculate_reaction_rate( | ||
| args.delta_impurity, sigma_eff, flux_spectrum | ||
|
|
@@ -161,7 +169,6 @@ def calculate_dose_for_source( | |
| logging.info("Calculating the Dose...") | ||
| # Determine the Dose for each nuclide | ||
| for nuclide, nuclide_activity in activities.items(): | ||
|
|
||
| # Convert to format in dose conversion spreadsheet | ||
| nuclide = normalise_nuclide_name(nuclide) | ||
|
|
||
|
|
@@ -210,7 +217,7 @@ def calculate_dose_for_source( | |
| else: | ||
| plt.savefig(f"{run_dir}/dose_{x1}_{y1}_{z1}.png") | ||
|
|
||
| return dose_array, x, y, z, total_dose | ||
| return dose_array, x, y, z, total_dose, activities | ||
|
|
||
|
|
||
| def calculate_dose_at_workstations( | ||
|
|
@@ -301,6 +308,7 @@ def process_sources(args: Namespace) -> None: | |
| dose_factors_df = pd.read_excel(fp) | ||
|
|
||
| dose_arrays = [] | ||
| sources = [] | ||
| # Check if a second point was provided - line source | ||
| if args.x2 is not None and args.y2 is not None and args.z2 is not None: | ||
| logging.info("Line source(s) selected") | ||
|
|
@@ -309,7 +317,7 @@ def process_sources(args: Namespace) -> None: | |
| for x1, y1, z1, x2, y2, z2 in zip( | ||
| args.x1, args.y1, args.z1, args.x2, args.y2, args.z2 | ||
| ): | ||
| dose_array, x, y, z, dose = calculate_dose_for_source( | ||
| dose_array, x, y, z, dose, activities = calculate_dose_for_source( | ||
| args, | ||
| x1, | ||
| y1, | ||
|
|
@@ -339,8 +347,8 @@ def process_sources(args: Namespace) -> None: | |
| logging.info("Point source(s) selected") | ||
|
|
||
| # Handle multiple coordinates being provided | ||
| for x1, y1, z1 in zip(args.x1, args.y1, args.z1): | ||
| dose_array, x, y, z, dose = calculate_dose_for_source( | ||
| for i, (x1, y1, z1) in enumerate(zip(args.x1, args.y1, args.z1)): | ||
| dose_array, x, y, z, dose, activities = calculate_dose_for_source( | ||
| args, | ||
| x1, | ||
| y1, | ||
|
|
@@ -352,8 +360,18 @@ def process_sources(args: Namespace) -> None: | |
| dose_factors_df, | ||
| ) | ||
| dose_arrays.append(dose_array) | ||
| if args.dump_source: | ||
|
||
| if args.m: | ||
| mass = args.m[i] | ||
| else: | ||
| mass = 1 | ||
| sources.append(PointSource(activities, [x1, y1, z1], mass=mass)) | ||
| calculate_dose_at_workstations(args, dose, x1, y1, z1, run_dir) | ||
|
|
||
| if args.dump_source: | ||
| global_source = GlobalPointSource(sources) | ||
| global_source.to_sdef(f"{run_dir}/source.sdef") # TODO | ||
|
||
|
|
||
| # If more than one dose array is present, sum the dose arrays (multiple sources) | ||
| if len(dose_arrays) > 1: | ||
| sum_vtr_files(dose_arrays, x, y, z, run_dir, masses=args.m) | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,9 +1,9 @@ | ||
| import os | ||
| from typing import List, Optional | ||
|
|
||
| import os | ||
| import numpy as np | ||
| from jsonargparse import ArgumentParser, Namespace, ActionConfigFile | ||
| import pandas as pd | ||
| from jsonargparse import ActionConfigFile, ArgumentParser, Namespace | ||
|
|
||
|
|
||
| def parse_arguments(args_list: Optional[List[str]] = None) -> Namespace: | ||
|
|
@@ -138,7 +138,12 @@ def parse_arguments(args_list: Optional[List[str]] = None) -> Namespace: | |
| type=str, | ||
| help="Path to STL files of ITER rooms that can be used for plotting", | ||
| ) | ||
|
|
||
| # Add the optional "mcnp" argument | ||
| parser.add_argument( | ||
| "--dump_source", | ||
|
||
| action="store_true", | ||
| help="Optional 'dump_source' argument to generate source.sdef.file for MCNP", | ||
| ) | ||
| # Parse the arguments | ||
| args = parser.parse_args(args_list) | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a good addition (for what is needed). I just note that as an action for the future that in the shielding module of the code the retrieval of gamma lines was done using the API for the IAEA NDS. Just for consistency, now we have this dependency, actigamma could also be used.