-
Notifications
You must be signed in to change notification settings - Fork 16
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
Separate depcode.py
into three files
#174
Conversation
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.
Hi @yardasol. Great work on this, I'm sure if took you some time to make sure you found all of the variable names that needed to updated. I have a few questions about some of the files. I will approve once you address my comments, although they are pretty minor.
- ``DepcodeSerpent`` → ``SerpentDepcode`` | ||
|
||
- ``template_inputfile_path`` → ``template_input_file_path`` | ||
- Changed `iter_inputfile` and `iter_matfile` to be attributes instead of parameters | ||
|
||
|
||
- ``DepcodeOpenmc`` is a ``Depcode`` subclass that interfaces with ``openmc``. This class implements the following functions | ||
- ``OpenMCDepcode`` is a ``Depcode`` subclass that interfaces with ``openmc``. This class implements the following functions |
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.
Is there any reason you have one with the arrow and one without? Is OpenMCDepcode
new? I thought you were renaming it.
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.
OpenMCDepcode
doesn't exist in v0.4.0 yet, so there's no need to indicate that the name has been changed inside the development period between v0.4.0 and v0.5.0.
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.
Ok. That makes sense.
from abc import ABC, abstractmethod | ||
|
||
class Depcode(ABC): |
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.
Couple things:
- are you importing the ABC class from this module into this module?
- Did you name this class
ABC
as in "abstract class"? Is this class ever seen by the user? If it is then this feels like a not-so intuitive class name for a user to have to remember. If the user doesn't see this, then disregard.
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 pattern indicates that Depcode
is an abstract class -- i.e. it inherits from the abc.ABC
class. The purpose of abstract classes is to provide a template for future class creation. The expected usage is something like
MyClass(Depcode)
def read_depcode_info():
do stuff
where MyClass
overrides the read_depcode_info
method (which doesn't currently do anything).
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.
I get the Depcode
being an abstract class part. My confusion is where the ABC
class is coming from. Is ABC
is being imported from the abc
module into an abc
module? If so, then is it another abc
module this is being pulled from? Or is the abc
module it's importing from a python package, like numpy or pandas?
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.
He's importing from the latter. My suggestion was to rename the file to avoid this confusion.
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.
I support this suggestion. Clearly I was confused by this.
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.
I picked abc.py
as it can hold many different classes that use abstract functions, but perhaps this isn't the best way of doing things.
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.
If that's the case, maybe just write out abstract_classes.py
?
self.iter_inputfile = {'geometry': './geometry.xml', | ||
'settings': './settings.xml'}, | ||
self.iter_matfile = './materials.xml' |
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.
Do you mean to leave these paths hardcoded? Wouldn't you want to read in the values of the template_input_file dictionary?
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.
I agree with this, it seems restrictive to have these hardcoded.
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.
They are hardcoded because OpenMC by default expects that the settings, geometry, and material files are named settings.xml
, geometry.xml
materials.xml
respectively. At the end of each reprocessing step, these files are the ones modified instead of the user's original OpenMC input files. The user has no need to specify a name for them.
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.
So the user can specify files that they created from any location, then the code will copy them to have these names and be in this location. Then the code continuously calls these copied files and edits them as needed?
I get hardcoding the names, if that is what OpenMC requires. But would the file path ever change?
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.
So the user can specify files that they created from any location, then the code will copy them to have these names and be in this location. Then the code continuously calls these copied files and edits them as needed?
Correct
I get hardcoding the names, if that is what OpenMC requires. But would the file path ever change?
The file path will only change if there's a change to OpenMC that requires us to change it as such.
def read_depcode_info(self): | ||
"""Parses initial OpenMC simulation info from the OpenMC output files | ||
and stores it in the `Depcode` object's ``sim_info`` attribute. | ||
""" |
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.
I'm assuming that most of the functions are placeholders for now, correct?
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 actually confuses me, too. These are no longer @abstractmethods
so shouldn't they do something?
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.
These are placeholders and will be implemented in a future PR in the near future. Right now these methods don't actually do anything.
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.
These are placeholders and will be implemented in a future PR in the near future. Right now these methods don't actually do anything.
@@ -46,7 +46,7 @@ def test_integration_2step_saltproc_no_reproc_heavy(setup): | |||
test_fuel_mdens = test_result['MAT_fuel_MDENS'][:, -1] | |||
|
|||
test_mdens_error = np.array(ref_fuel_mdens - test_fuel_mdens) | |||
np.testing.assert_array_equal(test_mdens_error, ref_mdens_error) | |||
np.testing.assert_array_almost_equal(test_mdens_error, ref_mdens_error) |
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.
Why are you saying almost equal
here? Is there some rounding error between values of the array here?
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.
I use this because monte-carlo codes are stochastic and can have slightly different results each time you run them, which would cause a assert_equal
statement to fail.
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.
So this test is based on some result out of Serpent or OpenMC then? If that's the case, can you specify a random seed? Or does doing that still have some small variation in the result?
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.
There can still be variation introduced by differences in hardware, compilers, etc.
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.
The default sensitivity of assert_almost_equal
is on the order of 10^-6, which I think is sufficiently small since we are comparing errors, not base values.
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.
That makes sense. And this test passes?
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.
Yes
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.
Good job @yardasol. There are some minor-ish changes. In particular I think your file names could be clearer. abc
and app
are not useful indicators of their contents.
@@ -0,0 +1,163 @@ | |||
from abc import ABC, abstractmethod |
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 file should be renamed to avoid a potential namespace conflict with abc
. Also so that it's clearer to users what lives here.
Be sure to use git mv abc.py some-other-name.py
to minimize the number of files in the commit.
from abc import ABC, abstractmethod | ||
|
||
class Depcode(ABC): |
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 pattern indicates that Depcode
is an abstract class -- i.e. it inherits from the abc.ABC
class. The purpose of abstract classes is to provide a template for future class creation. The expected usage is something like
MyClass(Depcode)
def read_depcode_info():
do stuff
where MyClass
overrides the read_depcode_info
method (which doesn't currently do anything).
@@ -240,9 +240,9 @@ def _create_depcode_object(depcode_input): | |||
"""Helper function for `run()` """ | |||
codename = depcode_input['codename'] | |||
if codename == 'serpent': | |||
depcode = DepcodeSerpent | |||
depcode = SerpentDepcode |
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.
I guess this is fine, lol. Why rearrange?
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.
Personal preference, as well as consistency with how we would refer to these in natural language (i,e, Serpent depletion code corresponds better to SerpentDepcode than DepcodeSerpent)
from saltproc import Materialflow | ||
from saltproc.abc import Depcode | ||
|
||
class OpenMCDepcode(Depcode): |
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.
@abachma2 example of Depcode
😄
def read_depcode_info(self): | ||
"""Parses initial OpenMC simulation info from the OpenMC output files | ||
and stores it in the `Depcode` object's ``sim_info`` attribute. | ||
""" |
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 actually confuses me, too. These are no longer @abstractmethods
so shouldn't they do something?
def depcode_openmc(cwd): | ||
"""DepcodeOpenMC object for unit tests""" | ||
def openmc_depcode(cwd): | ||
"""OpenMCDepcode object for unit tests""" | ||
saltproc_input = (cwd / 'openmc_data' / 'tap_input.json').as_posix() | ||
_, _, _, object_input = read_main_input(saltproc_input) |
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.
I don't love this... I get that the first several variables are unused -- but I think they should still have proper names. I don't think there are any performance benefits to this either. This is just a preference though, so if you have a compelling reason to use underscores go ahead, I suppose.
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.
My perspective is that they are not relevant to anything else in the function, and giving them a null-like name indicates that. Maybe @munkm has some perspective on this?
self.iter_inputfile = './iter_input' | ||
self.iter_matfile = './iter_mat' |
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.
Are these files created dynamically?
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.
Yes, and their names will be inter_input
and iter_mat
respectively. They are hardcoded because they don't really need to be seen by the user.
self.iter_inputfile = {'geometry': './geometry.xml', | ||
'settings': './settings.xml'}, | ||
self.iter_matfile = './materials.xml' |
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.
I agree with this, it seems restrictive to have these hardcoded.
subprocess.check_output( | ||
args, | ||
cwd=os.path.split(self.template_inputfile_path)[0], | ||
stderr=subprocess.STDOUT) |
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.
Just an FYI using subprocess.STDOUT can create some challenges for users on different platforms.
I had problems with it this summer when using watts
. watts-dev/watts#52.
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.
Namely users with
- WSL2
- windows
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.
Thanks for the heads up. I'll look into fixing this as part of a PR that addresses #173
@samgdotson I agree we should rename |
I am okay with putting this into a different PR. I see that renaming the file is on the To Do list for that PR, and I like the name you suggest there in for |
@samgdotson @abachma2 Is this good to be merged? |
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.
I am approving this PR. I won't merge though until after @samgdotson gives his approval as well.
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.
I guess this is fine if the issues raised will be resolved later.
…-depcode Separate `depcode.py` into three files 2cf2788
…rate-depcode Separate `depcode.py` into three files 2cf2788
…rate-depcode Separate `depcode.py` into three files 2cf2788
Summary of changes
The purpose of this PR is to make the changes in #172 easier to see for reviewers.
Specifically, this PR does the following:
DepcodeSerpent
->SerpentDepcode
DepcodeOpenMC
->OpenMCDepcode
depcode.py
file into three difference files:abc.py
, storingDepcode
openmc_depcode.py
, storingOpenMCDepcode
serpent_depcode.py
, storingSerpentDepcode
Types of changes
Required for Merging
Associated Issues and PRs
Depcode
class #172Associated Developers
Checklist for Reviewers
Reviewers should use this link to get to the
Review Checklist before they begin their review.