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

Finished Sofast HDF5 IO #31

Merged
merged 16 commits into from
Mar 20, 2024
Merged

Conversation

braden6521
Copy link
Collaborator

@braden6521 braden6521 commented Mar 18, 2024

Finished the SofastFringeProcess class's HDF5 saving infrastructure.

  • All of ProcessSofastFringe's data classes are saved/loaded to HDF5 files automatically.
  • Cleaned up some random files in /test/data/output/ that weren't supposed to be in repo.
  • Moved an example file (view_camera_distortion) that was accidentally in the wrong folder
  • Created HDF5_IO_Abstract() and HDF_SaveAbstract() classes to hdf5_tools.py. These define standard input/output methods to save to HDF5 files.
  • Added HDF input/output methods to Surface2Dxxx classes.
  • Added HDF input/output unit tests to Surface2Dxxx classes.
  • Sofast now inherits from HDF_SaveAbstract()
  • Modified SofastFringe so that input surface definitions are no longer dictionaries, but rather Surface2DParabolic or Surface2DPlano classes. (The old dictionary input method was basically a dictionary version of a data class). Now, all data classes within SofastFringe now support HDF5 saving natively.
  • Updated SofastFringe integration tests to use Surface2Dxxx classes.
  • Updated the SofastFringe examples to use this new surface definition method.
  • Added use of logtools to SofastFringe examples (Thanks to Bens' awesome idea).
  • Added use of logtools to ProcessSofastFringe class.
  • Added use of filetools to SofastFringe examples
  • Renamed SofastFringe examples so names follow coarse->fine convention.

@braden6521 braden6521 self-assigned this Mar 18, 2024
@braden6521 braden6521 requested a review from bbean23 March 18, 2024 21:22
@braden6521 braden6521 marked this pull request as draft March 18, 2024 21:23
@braden6521 braden6521 marked this pull request as ready for review March 18, 2024 22:20
@e10harvey
Copy link
Collaborator

@braden6521: Please rebase this on-top of develop.

Copy link
Collaborator

@bbean23 bbean23 left a comment

Choose a reason for hiding this comment

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

Please address all comments and ping me, so I can approve then.

ft.create_directories_if_necessary(dir_save)

# Set up logger
lt.logger(join(dir_save, 'log.txt'))
Copy link
Collaborator

Choose a reason for hiding this comment

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

It's typically better to do this step outside a function, such as in the if __name__ == "__main__": control, because lt.logger() should only be called once per process.

That being said, I think it's ok to leave it here, since the example_driver() function essentially is the main process.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Sounds good, I'll make sure to do that in the future.
I'll leave it here for the time being for the reason you mentioned. Also the save_dir needs to be set up before the log, so I'm fine with leaving it in this file.

@@ -410,6 +410,37 @@ def process_multifacet_geometry(
list[cdc.CalculationImageProcessingFacet],
cdc.CalculationError,
]:
"""Processes optic geometry for multifacet deflectometry measurement
Copy link
Collaborator

Choose a reason for hiding this comment

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

Yesssssssssssssss! Love me some docstrings!

ensemble_data : DefinitionEnsemble
Ensemble definition object
mask_raw : ndarray
Raw calculated mask
Copy link
Collaborator

Choose a reason for hiding this comment

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

What is the type of the mask? Is it a boolean WxH array?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Documentation updated

calculation_data_classes.CalculationImageProcessingGeneral
list[calculation_data_classes.CalculationDataGeometryFacet]
list[calculation_data_classes.CalculationImageProcessingFacet]
calculation_data_classes.CalculationError]
Copy link
Collaborator

Choose a reason for hiding this comment

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

Two notes here:

  1. If you'd like, you can give example names and also descriptions in your return values. I at least find it helpful. I pulled the variable names from 300 lines below here and made up some example descriptions:
"""
...
Returns
-------
data_geometry_general: calculation_data_classes.CalculationDataGeometryGeneral
    A general form describing the geometry of the facet.
data_image_processing_general: calculation_data_classes.CalculationImageProcessingGeneral
    A general form describing what processing was done to the input images to this process_multifacet_geometry() function.
data_geometry_facet: list[calculation_data_classes.CalculationDataGeometryFacet]
    The geometry of each facet, one per facet. Index 0 is the top left facet, and index -1 is the bottom right facet. They are listed in left-to-right, top-to-bottom order. (ie index 1 == facet in the top row, second from left, index 2 == ...)
data_image_processing_facet: list[calculation_data_classes.CalculationImageProcessingFacet]
    The image processing that was done to each facet.
data_error: calculation_data_classes.CalculationError]
    All the errors encountered during image processing.
"""
  1. Is the last return supposed to also be a list?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

  1. Documentation updated, thanks for the suggestion.
  2. Not supposed to be a list, just a copy-paste error (I fixed all instances of this error).

Test.test_int_points()

print('All tests run.')
unittest.main()
Copy link
Collaborator

Choose a reason for hiding this comment

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

Thank you! I highly prefer this style of calling unit tests! 🥳

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Same, I've recently started converting to this way.



@dataclass
class ParamsSlopeSolverParaboloid:
Copy link
Collaborator

Choose a reason for hiding this comment

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

Should this inherit from ParamsSlopeSolver?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Wow, I just left these classes unfinished...🤦‍♂️ ParamsSlopeSolver is now ParamsSlopeSolverAbstract and is inherited by ParamsSlopeSolverParabolic and ParamsSlopeSolverPlano. Thanks for the catch!

Copy link
Collaborator

Choose a reason for hiding this comment

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

Code reviews ftw

@@ -327,3 +328,35 @@ def shift_all(self, v_align_optic_step: Vxyz) -> None:
self.v_optic_cam_optic += v_align_optic_step
self.v_screen_points_optic += v_align_optic_step
self.v_optic_screen_optic += v_align_optic_step

def save_to_hdf(self, file: str, prefix: str = ''):
Copy link
Collaborator

Choose a reason for hiding this comment

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

This is more of a preference comment than a "best practices" or "requirements" comment. I like naming my conversion methods starting with either "to_" or "from_", and then they're easy to identify with the IDE. What do you think?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

My current convention is "save_to_xxx" or "load_from_xxx." (I believe I have HDF5 and CSV methods with that convention). But I didn't put too much thought into those names; I'm totally fine switching to the standard you mentioned. Shall we move toa to_csv, form_csv, to_hdf, from_hdf, etc. standard.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Let's use to_* and from_*. From some quick googling those seem to be the more standard way of naming conversion methods.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Or, simply save(file_path_name_ext: str) and throw an error for anything that isn't '.h5'. Either way is good.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

@bbean23, sounds good! I will likely put this in separate PR so this one doesn't get too cluttered.

"""Abstract class for saving to HDF5 format"""

@abstractmethod
def save_to_hdf(self, file: str, prefix: str = '') -> None:
Copy link
Collaborator

Choose a reason for hiding this comment

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

I really like this interface! Having a "prefix" should really clean up how we interact with HDF5 files.

@braden6521
Copy link
Collaborator Author

@braden6521: Please rebase this on-top of develop.

Done. This branch has been rebased on top of develop.

@braden6521
Copy link
Collaborator Author

@bbean23, I believe I addressed all your comments.

bbean23
bbean23 previously approved these changes Mar 20, 2024
Copy link
Collaborator

@bbean23 bbean23 left a comment

Choose a reason for hiding this comment

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

Looks good! Last thing to do is change save_to_hdf5->to_hdf5 and load_from_hdf5->from_hdf5. However, that can happen whenever. Feel free to merge.

Copy link
Collaborator

@bbean23 bbean23 left a comment

Choose a reason for hiding this comment

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

Still looks good after the rebase. Approved!

@braden6521 braden6521 merged commit 5c3a408 into sandialabs:develop Mar 20, 2024
0 of 3 checks passed
@braden6521 braden6521 deleted the surface_params branch April 15, 2024 19:08
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.

3 participants