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

Refactor parsing of results files #176

Open
wants to merge 6 commits into
base: main
Choose a base branch
from

Conversation

wtbarnes
Copy link
Member

@wtbarnes wtbarnes commented Nov 4, 2024

Fixes #86

This pull requests does a few things though is mainly focused on refactoring the parsing of the results files to try and simplify things:

  • Move all file parsing logic to standalone functions in pydrad/parse/util.py that return astropy.table.QTable objects rather than arrays
  • Properties on Strand are only dynamically generated if there are many of them or if they are unknown ahead of time (e.g. for the .ine files). Otherwise they are explicitly listed on Profile.
  • Quantities are now pulled out of the resulting tables by column name rather than relying on indexing an array. This should be more robust.
  • All results files are now optional except for the .amr files. If the .phy files are not read (or not present), the thermodynamic quantities are computed from the conserved quantities in the .amr files. See Function for calculating thermodynamic variables from conserved variables #86.

TODOs:

  • Docstrings for quantities on Profile
  • Create issue to track case where .amr file has an additional column for the electron mass density

Copy link

codecov bot commented Nov 4, 2024

Codecov Report

Attention: Patch coverage is 75.90361% with 40 lines in your changes missing coverage. Please review.

Project coverage is 71.30%. Comparing base (557e41a) to head (43bfc03).

Files with missing lines Patch % Lines
pydrad/parse/util.py 60.00% 18 Missing ⚠️
pydrad/parse/parse.py 88.28% 13 Missing ⚠️
pydrad/configure/configure.py 10.00% 9 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #176      +/-   ##
==========================================
+ Coverage   70.41%   71.30%   +0.89%     
==========================================
  Files          11       12       +1     
  Lines         730      798      +68     
==========================================
+ Hits          514      569      +55     
- Misses        216      229      +13     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@wtbarnes wtbarnes marked this pull request as draft November 4, 2024 22:09
@wtbarnes wtbarnes changed the title Minor refactoring of parsing and configuration Refactor parsing of results files Nov 7, 2024
@wtbarnes wtbarnes requested a review from jwreep November 7, 2024 20:22
@wtbarnes wtbarnes marked this pull request as ready for review November 7, 2024 20:22
"""
Parse the ``.hstate`` files containing the hydrogen level populations as a function of position
"""
columns = [f'level_population_hydrogen_{i}' for i in range(1,7)]
Copy link
Member

Choose a reason for hiding this comment

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

level_population_hydrogen_3 is not really understandable at first glance. Level 6 is also not the 6th level, it's the ionized fraction.

Is there a better naming scheme we could use?

Copy link
Member

Choose a reason for hiding this comment

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

Also, perhaps adding a "neutral fraction" property, which is just the sum of levels 1 through 5, might be helpful. It's sometimes helpful to consider ions vs neutrals in the chromosphere.

Copy link
Member Author

Choose a reason for hiding this comment

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

I'm open to any better naming scheme! I think I probably named these somewhat arbitrarily as I didn't know what else to call them.

Also 👍 on a derived neutral fraction property. I would suggest that be its own PR.

Copy link
Member

Choose a reason for hiding this comment

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

Perhaps just simplifying hydrogen_level_i for the first five, and ionized_fraction for the last. I'm not sure if there's a much better name without abbreviations, but alternatively maybe HI_level_i and HII_fraction. Not sure.

@@ -415,7 +425,8 @@ def maximum_cells(self):
refinement level and :math:`n_{min}` is the minimum allowed number of
grid cells. Optionally, if the maximum number of cells is specified
in ``config['grid']['maximum_cells']``, this value will take
precedence.
precedence. In general, it is better to set this value explicitly to a sufficiently
large value.
Copy link
Member

Choose a reason for hiding this comment

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

What is sufficiently large? Perhaps 1 Mm per cell at the minimum? I think a simple example number would be useful as a comment.

Copy link
Member Author

Choose a reason for hiding this comment

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

The default configuration now explicitly uses a value of 30000 which is what the HYDRAD GUI uses. Beyond that, I don't have a sense of what sufficiently large is. For low refinement levels (e.g. 4), the $2^Ln_{min}$ rule of thumb does not seem to hold.

pydrad/parse/parse.py Show resolved Hide resolved
"""
Parse the hydrodynamics results file
Parse the adaptive mesh grid file
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
Parse the adaptive mesh grid file
Parse the adaptive mesh refinement (.AMR) file

"""
Parse the adaptive mesh grid file
Parse the hydrodynamics results file
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
Parse the hydrodynamics results file
Parse the physical variables (.PHY) file

Nitpicking just to clarify what the file extension means

self._grid_centers[i] = tmp[0]
self._grid_widths[i] = tmp[1]
if not self._phy_filename.is_file():
log.warning(f'{self._phy_filename} not found. Skipping parsing of phy files. Set read_phy=False to suppress this warning.')
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
log.warning(f'{self._phy_filename} not found. Skipping parsing of phy files. Set read_phy=False to suppress this warning.')
log.warning(f'{self._phy_filename} not found. Skipping parsing of .phy files. Set read_phy=False to suppress this warning.')

def electron_pressure(self) -> u.Unit('dyne cm-2'):
if hasattr(self, '_phy_data'):
return self._phy_data['electron_pressure']
gamma = 5/3
Copy link
Member

Choose a reason for hiding this comment

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

Maybe this shouldn't be hard coded? I think it's also found in the constants.h file. I don't think it would ever be updated, so probably not worrisome.

Copy link
Member Author

Choose a reason for hiding this comment

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

Agreed. I was mildly annoyed that this isn't already defined in astropy.constants. We could create a constants file and stick it in there.

Copy link
Member

Choose a reason for hiding this comment

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

I'd say astropy should add it, but the truth is that this isn't a constant, so much as a value specific to monatomic gas.

A constants file is probably a reasonable way to deal with this.

def ion_pressure(self) -> u.Unit('dyne cm-2'):
if hasattr(self, '_phy_data'):
return self._phy_data['ion_pressure']
gamma = 5/3
Copy link
Member

Choose a reason for hiding this comment

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

Ditto with my previous comment. Also, we're setting the same variable twice, and they should not differ between electrons/ions.


@property
@u.quantity_input
def ion_pressure(self) -> u.Unit('dyne cm-2'):
Copy link
Member

Choose a reason for hiding this comment

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

Perhaps worth adding a total pressure variable = P_e + P_H?


def read_ine_file(filename, n_s):
"""
Parse ``.ine`` files containing ionization fraction as a function of position
Copy link
Member

Choose a reason for hiding this comment

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

Similar to the comments above, I wonder if it's worth just clarifying what the file extensions mean. For example,

Suggested change
Parse ``.ine`` files containing ionization fraction as a function of position
Parse Ionization Non-Equilibrium ``.ine`` files containing ionization fraction as a function of position

lines = f.readlines()
# First parse all of the population fraction arrays
# NOTE: Have to calculate the number of elements we have
# computed population fractions for as we do not necessarily
Copy link
Member

Choose a reason for hiding this comment

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

This could be pulled from ./Radiation_Model/config/elements_neq.cfg, rather than calculated. Not sure if that's faster/slower, but it is an alternative option.

Copy link
Member Author

Choose a reason for hiding this comment

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

True. As I commented above, I've tried to make this only dependent on the results files themselves such that you can parse results even if all of the usual HYDRAD files aren't there. Reading from the neq file seems just as onerous as having to specify the number of coordinates.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Function for calculating thermodynamic variables from conserved variables
2 participants