Skip to content

Commit eb71369

Browse files
authored
Merge pull request #252 from braden6521/sofast_interface_class
Sofast interface class
2 parents 1753f01 + 67ebf29 commit eb71369

File tree

9 files changed

+741
-583
lines changed

9 files changed

+741
-583
lines changed

contrib/app/sofast/SofastCommandLineInterface.py

Lines changed: 0 additions & 583 deletions
This file was deleted.

doc/source/example/sofast_fringe/config.rst

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,3 +64,13 @@ Process SOFAST Temperature Experiment Data
6464
.. automodule:: example.sofast_fringe.sofast_temperature_analysis
6565
:members:
6666
:show-inheritance:
67+
68+
69+
Running SOFAST with Command Line Tool
70+
=====================================
71+
72+
.. currentmodule:: example.sofast_fringe.sofast_command_line_tool
73+
74+
.. automodule:: example.sofast_fringe.sofast_command_line_tool
75+
:members:
76+
:show-inheritance:

doc/source/library_reference/app/sofast/config.rst

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,16 @@ opencsp.app.sofast.lib.ParamsSofastFixed
7878
:undoc-members:
7979
:show-inheritance:
8080

81+
opencsp.app.sofast.lib.SofastInterface
82+
======================================
83+
84+
.. currentmodule:: opencsp.app.sofast.lib.SofastInterface
85+
86+
.. automodule:: opencsp.app.sofast.lib.SofastInterface
87+
:members:
88+
:undoc-members:
89+
:show-inheritance:
90+
8191
opencsp.app.sofast.lib.SystemSofastFringe
8292
=========================================
8393

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
"""
2+
Command-line tool for processing optical measurements using SOFAST.
3+
4+
This module provides a command-line interface for processing optical measurements
5+
using the SOFAST framework. It sets up the necessary components for image acquisition,
6+
image projection, and SOFAST processing, allowing users to run measurements and
7+
generate results based on the provided calibration and configuration files.
8+
9+
NOTE:
10+
11+
- To run this example, you will need a full physical SOFAST setup. This includes
12+
a camera, display (LCD screen or projector), and a mirror to test.
13+
- The calibration files required to run this example are not included in the
14+
OpenCSP repository. You will need to generate your own for your own system.
15+
16+
Usage:
17+
18+
To run the command-line tool, provide the paths to the calibration directory and the
19+
directory where results should be saved as command-line arguments.
20+
21+
For example:
22+
23+
```
24+
python sofast_command_line_tool.py path/to/calibration/files path/to/save/outputs
25+
```
26+
"""
27+
28+
from os.path import join
29+
import sys
30+
31+
from opencsp.app.sofast.lib.DefinitionFacet import DefinitionFacet
32+
from opencsp.app.sofast.lib.DotLocationsFixedPattern import DotLocationsFixedPattern
33+
from opencsp.app.sofast.lib.DisplayShape import DisplayShape
34+
from opencsp.app.sofast.lib.Fringes import Fringes
35+
from opencsp.app.sofast.lib.SofastInterface import (
36+
SofastInterface,
37+
SofastCommonRunData,
38+
SofastFixedRunData,
39+
SofastCommonProcessData,
40+
SofastFringeProcessData,
41+
SofastFixedProcessData,
42+
)
43+
from opencsp.app.sofast.lib.SpatialOrientation import SpatialOrientation
44+
from opencsp.common.lib.camera.Camera import Camera
45+
from opencsp.common.lib.camera.ImageAcquisition_DCAM_mono import ImageAcquisition
46+
from opencsp.common.lib.csp.MirrorParametric import MirrorParametric
47+
from opencsp.common.lib.deflectometry.ImageProjection import ImageProjection
48+
from opencsp.common.lib.deflectometry.Surface2DParabolic import Surface2DParabolic
49+
from opencsp.common.lib.geometry.Vxy import Vxy
50+
from opencsp.common.lib.geometry.Vxyz import Vxyz
51+
from opencsp.common.lib.geometry.RegionXY import RegionXY
52+
import opencsp.common.lib.tool.log_tools as lt
53+
54+
55+
def example_sofast_command_line_tool(dir_cal: str, dir_save: str) -> None:
56+
"""
57+
Processes optical measurements using SOFAST via command-line interface.
58+
59+
This function performs the following steps:
60+
61+
1. Sets up logging for the processing session.
62+
2. Configures image acquisition settings for the camera.
63+
3. Loads image projection data from an HDF5 file.
64+
4. Initializes the SOFAST interface and fringe system.
65+
5. Loads necessary processing data, including facet definitions, camera data,
66+
spatial orientation, display shape, and dot locations.
67+
6. Configures plotting options and save paths for output files.
68+
7. Executes the SOFAST processing routine.
69+
70+
Parameters
71+
----------
72+
dir_cal : str
73+
The directory path containing calibration files required for processing,
74+
including image projection, facet definitions, camera data, and spatial
75+
orientation data.
76+
dir_save : str
77+
The directory path where the output results and figures will be saved.
78+
79+
Example
80+
-------
81+
To run the SOFAST command-line tool, execute the script with the required
82+
directories as arguments:
83+
84+
>>> python script_name.py /path/to/calibration /path/to/save/results
85+
86+
The results will be saved in the specified directory.
87+
"""
88+
# Set up OpenCSP logger
89+
lt.logger(join(dir_save, "log.txt"), lt.log.WARN)
90+
91+
# Define image acquisition
92+
image_acquisition_in = ImageAcquisition(instance=0) # First camera instance found
93+
image_acquisition_in.frame_size = (1626, 1236) # Set frame size
94+
image_acquisition_in.gain = 230 # Set gain (higher=faster/more noise, lower=slower/less noise)
95+
96+
# Define image projection
97+
file_image_projection = join(dir_cal, "image_projection_optics_lab_landscape_square.h5")
98+
image_projection = ImageProjection.load_from_hdf(file_image_projection)
99+
image_projection.display_data.image_delay_ms = 200 # define projector-camera delay
100+
101+
# Setup and run Sofast Interface
102+
inter = SofastInterface(image_acquisition_in)
103+
104+
# Initialize Sofast Fringe system
105+
fringes = Fringes.from_num_periods(4, 4)
106+
inter.data_sofast_common_run = SofastCommonRunData(
107+
measure_point_optic=Vxyz((0, 0, 0)), dist_optic_screen=10, name_optic="Some Optic"
108+
)
109+
inter.initialize_sofast_fringe(fringes)
110+
111+
# Initialize Sofast Fixed system
112+
inter.data_sofast_fixed_run = SofastFixedRunData(origin=Vxy((100, 200)))
113+
inter.initialize_sofast_fixed()
114+
115+
# Initialize Sofast processing data
116+
file_facet = join(dir_cal, "facet_NSTTF.json")
117+
file_camera = join(dir_cal, "camera_sofast_optics_lab_landscape_2025_02.h5")
118+
file_ori = join(dir_cal, "spatial_orientation_optics_lab_landscape.h5")
119+
file_display_shape = join(dir_cal, "display_shape_optics_lab_landscape_square_distorted_3d_100x100.h5")
120+
file_dot_locs = join(dir_cal, "dot_locations_optics_lab_landscape_square_width3_space6.h5")
121+
surface_fringe = Surface2DParabolic((100, 100), False, 10)
122+
surface_fixed = Surface2DParabolic((100, 100), False, 1)
123+
124+
inter.data_sofast_common_proccess = SofastCommonProcessData(
125+
facet_definition=DefinitionFacet.load_from_json(file_facet),
126+
camera=Camera.load_from_hdf(file_camera),
127+
spatial_orientation=SpatialOrientation.load_from_hdf(file_ori),
128+
)
129+
inter.data_sofast_fringe_process = SofastFringeProcessData(
130+
display_shape=DisplayShape.load_from_hdf(file_display_shape), surface_2d=surface_fringe
131+
)
132+
inter.data_sofast_fixed_process = SofastFixedProcessData(
133+
fixed_pattern_dot_locs=DotLocationsFixedPattern.load_from_hdf(file_dot_locs), surface_2d=surface_fixed
134+
)
135+
136+
# Set up plotting
137+
shape = RegionXY.rectangle(1.5)
138+
focal_length = 100
139+
inter.plotting.optic_reference = MirrorParametric.generate_symmetric_paraboloid(focal_length, shape)
140+
inter.plotting.options_ray_trace_vis.to_plot = False
141+
inter.plotting.options_file_output.number_in_name = False
142+
inter.plotting.options_file_output.to_save = True
143+
144+
# Set up save paths
145+
inter.paths.dir_save_fixed = dir_save
146+
inter.paths.dir_save_fringe = dir_save
147+
inter.paths.dir_save_fringe_calibration = dir_save
148+
149+
# Run
150+
inter.run_cli()
151+
152+
153+
if __name__ == "__main__":
154+
dir_cal_in = sys.argv[1]
155+
dir_save_in = sys.argv[2]
156+
example_sofast_command_line_tool(dir_cal_in, dir_save_in)

opencsp/app/sofast/lib/Fringes.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
1+
"""Representation sinusoidal pattern (Fringe) used in a Sofast measurement."""
2+
13
import numpy as np
24

35

46
class Fringes:
7+
"""Class that handles calculating the sinusoidal fringes used in a SOFAST
8+
calculation. A fringe is an image whos intensity varies in either x or y
9+
according to a sinusoid."""
10+
511
def __init__(self, periods_x: list, periods_y: list):
612
"""
713
Representation of projected fringe images.

opencsp/app/sofast/lib/ImageCalibrationScaling.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66

77

88
class ImageCalibrationScaling(ImageCalibrationAbstract):
9+
"""Class that handles performing a pixel-wise calibration that 'scales' each pixel
10+
in a Sofast image according to a camera-projector-response calibration curve."""
11+
912
@staticmethod
1013
def get_calibration_name() -> str:
1114
"""The name of this calibration class type"""

0 commit comments

Comments
 (0)