-
Notifications
You must be signed in to change notification settings - Fork 16
Open
Description
Contact Details
No response
What happened?
RenderControlPowerpointPresentation.presentation fails with:
RuntimeError: ERROR: In copy_file(), requested output directory does not exist:
Version
develop@9d405367fa1f4030458ca14e522e77b1f72a37c8
What OS are you seeing this on?
MacOS
Relevant dependency versions
Python 3.10.16
ffmpeg version 7.1 Copyright (c) 2000-2024 the FFmpeg developers
built with Apple clang version 16.0.0 (clang-1600.0.26.4)
configuration: --prefix=/opt/homebrew/Cellar/ffmpeg/7.1_4 --enable-shared --enable-pthreads --enable-version3 --cc=clang --host-cflags= --host-ldflags='-Wl,-ld_classic' --enable-ffplay --enable-gnutls --enable-gpl --enable-libaom --enable-libaribb24 --enable-libbluray --enable-libdav1d --enable-libharfbuzz --enable-libjxl --enable-libmp3lame --enable-libopus --enable-librav1e --enable-librist --enable-librubberband --enable-libsnappy --enable-libsrt --enable-libssh --enable-libsvtav1 --enable-libtesseract --enable-libtheora --enable-libvidstab --enable-libvmaf --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libxvid --enable-lzma --enable-libfontconfig --enable-libfreetype --enable-frei0r --enable-libass --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libspeex --enable-libsoxr --enable-libzmq --enable-libzimg --disable-libjack --disable-indev=jack --enable-videotoolbox --enable-audiotoolbox --enable-neon
libavutil 59. 39.100 / 59. 39.100
libavcodec 61. 19.100 / 61. 19.100
libavformat 61. 7.100 / 61. 7.100
libavdevice 61. 3.100 / 61. 3.100
libavfilter 10. 4.100 / 10. 4.100
libswscale 8. 3.100 / 8. 3.100
libswresample 5. 3.100 / 5. 3.100
libpostproc 58. 3.100 / 58. 3.100
Package Version
----------------------------- ----------
alabaster 0.7.13
appnope 0.1.3
astroid 3.1.0
asttokens 2.4.1
attrs 24.2.0
Babel 2.14.0
beautifulsoup4 4.12.3
black 24.3.0
bleach 6.1.0
certifi 2023.11.17
chardet 5.2.0
charset-normalizer 3.3.2
click 8.1.7
codemetrics 0.11.7
comm 0.2.0
contourpy 1.2.0
coverage 7.4.0
cycler 0.12.1
Cython 3.0.6
debugpy 1.8.0
decorator 5.1.1
defusedxml 0.7.1
dill 0.3.8
docutils 0.20.1
et-xmlfile 1.1.0
exceptiongroup 1.2.0
executing 2.0.1
fastjsonschema 2.20.0
fonttools 4.46.0
gitdb 4.0.11
GitPython 3.1.43
h5py 3.12.1
idna 3.6
imageio 2.34.1
imagesize 1.4.1
iniconfig 2.0.0
ipykernel 6.29.4
ipython 8.18.1
isort 5.13.2
jedi 0.19.1
Jinja2 3.1.2
joblib 1.4.0
jsonschema 4.23.0
jsonschema-specifications 2023.12.1
jupyter_client 8.6.0
jupyter_core 5.5.0
jupyterlab_pygments 0.3.0
kiwisolver 1.4.5
lizard 1.17.10
lxml 4.9.3
markdown-it-py 3.0.0
MarkupSafe 2.1.3
matplotlib 3.8.2
matplotlib-inline 0.1.6
mccabe 0.7.0
mdit-py-plugins 0.4.0
mdurl 0.1.2
mistune 3.0.2
mpmath 1.3.0
mypy-extensions 1.0.0
myst-parser 2.0.0
nbclient 0.10.0
nbconvert 7.16.4
nbformat 5.10.4
nbsphinx 0.9.5
nest-asyncio 1.5.8
numpy 1.26.4
opencv-contrib-python 4.5.5.64
openpyxl 3.1.2
packaging 23.2
pandas 2.2.2
pandocfilters 1.5.1
parso 0.8.3
pathspec 0.12.1
pexpect 4.9.0
pillow 10.3.0
pip 23.3.2
pip-licenses 4.4.0
platformdirs 4.1.0
pluggy 1.5.0
ply 3.11
prettytable 3.10.0
prompt-toolkit 3.0.41
psutil 5.9.6
ptyprocess 0.7.0
pure-eval 0.2.2
Pygments 2.17.2
pygount 1.6.1
pylint 3.1.0
Pyomo 6.7.0
pyparsing 3.1.1
pyproj 3.6.1
pypylon 3.0.0
pysolar 0.11
pytest 8.2.1
pytest-cov 4.1.0
pytest-xvfb 3.0.0
python-dateutil 2.8.2
python-pptx 0.6.23
pytz 2024.1
PyVirtualDisplay 3.0
PyYAML 6.0.1
pyzmq 25.1.2
rawpy 0.21.0
referencing 0.35.1
requests 2.31.0
rich 13.7.1
rpds-py 0.20.0
scikit-learn 1.4.2
scipy 1.13.1
setuptools 68.2.2
six 1.16.0
smmap 5.0.1
snowballstemmer 2.2.0
soupsieve 2.6
Sphinx 7.2.6
sphinx-argparse 0.4.0
sphinx-rtd-theme 2.0.0
sphinxcontrib-applehelp 1.0.7
sphinxcontrib-devhelp 1.0.5
sphinxcontrib-htmlhelp 2.0.4
sphinxcontrib-jquery 4.1
sphinxcontrib-jsmath 1.0.1
sphinxcontrib-qthelp 1.0.6
sphinxcontrib-serializinghtml 1.1.9
stack-data 0.6.3
sympy 1.12
threadpoolctl 3.4.0
tinycss2 1.3.0
tomli 2.0.1
tomlkit 0.12.4
tornado 6.4
tqdm 4.66.4
traitlets 5.14.0
typing_extensions 4.9.0
tzdata 2023.3
urllib3 2.1.0
wcwidth 0.2.12
webencodings 0.5.1
wheel 0.42.0
XlsxWriter 3.1.9python script that produces the error
# Create power point presentation
presentation = rcpp.RenderControlPowerpointPresentation()
slide_control = rcps.RenderControlPowerpointSlide()
images = [pi.PowerpointImage(join(dir_save_cur, "Slope_X_measured_xy.png"))]
texts = [pt.PowerpointText("slope x measured")]
slide = ps.PowerpointSlide(slide_control, images, texts)
presentation.add_slide(slide)
presentation.save(dir_save_cur)Relevant console output
ERROR: In copy_file(), requested output directory does not exist: /tmp/tmp/PowerpointImage/images/tmp/0_0.png
FAILED
=============================================================================================================================================== FAILURES ===============================================================================================================================================
____________________________________________________________________________________________________________________________________________ example_laptop ____________________________________________________________________________________________________________________________________________
def example_laptop():
"""Performs processing of previously collected SOFAST data using a laptop webcam and a cosmetic mirror.
1. Load saved single facet SOFAST collection data from HDF5 file
2. Save projected sinusoidal fringe images to PNG format
3. Save captured sinusoidal fringe images and mask images to PNG format
4. Processes data with SOFAST and save processed data to HDF5
5. Generate plot suite and save images files
"""
# General setup
# =============
# Define save dir
dir_save = join(dirname(__file__), 'data/output/laptop')
ft.create_directories_if_necessary(dir_save)
# Set up logger
lt.logger(join(dir_save, 'example_laptop_log.txt'), lt.log.INFO)
# Phase 1: Setup a sofast laptop experiment by loading the calibration data
# (note that this data has already been collected for this opencsp example)
# =========================================================================
# Load the calibration data from physically setting up the laptop and cosmetic mirror in your room.
dir_calibration_data = join(dirname(__file__), 'data/calibration')
# This calibration data was prepared by doing the following:
# 1) Get resolution of laptop screen and use this to adjust the display size to the desired location
# NOTE: if a screen scale is applied, this may need to be applied to input dimensions as well.
# NOTE: If using two screens with difference scales it is recommended to set the scale to be the same for both monitors.
# file_calibration = join(dir_measurement_data, '20240515_104737_measurement_fringe.h5')
# 2) We assume that the laptop screen has little to no distortion and use the 2d rectangular definition.
# NOTE: for setting up your own laptop sofast, open display_rectangular.h5 via HDFView, set screen x/y in meters, and save it.
file_display = join(dir_calibration_data, 'screen_laptop_full/display_rectangular.h5')
# 3) NOTE: We measured the distance from the center of the crosshairs on the cosmetic mirror to the center of the laptop webcam lens
# NOTE: for setting up your own laptop sofast, open spatial_orientation.h5 via HDFView, set optic_oriented to 0, set r_cam_screen to (0, 0, 0), set v_cam_screen_cam to x=?, y=?, z=0, and save it
file_orientation = join(dir_calibration_data, 'screen_laptop_full/spatial_orientation.h5')
# 4) NOTE: camera.h5 was measured by following 2.4.1 of the sofast user guide. See https://sandia-csp.app.box.com/file/1636393938364.
file_laptop_camera = join(dir_calibration_data, 'camera_calibration/camera.h5')
# This data was collected by running the sofast command line client with the above calibration data on the cosmetic mirror, and laptop webcam in our room
dir_measurement_data = join(dirname(__file__), 'data/large_cosmetic_mirror')
file_measurement = join(dir_measurement_data, 'measurement.h5')
file_calibration = join(dir_measurement_data, 'calibration.h5')
ex_calibration = ImageCalibrationScaling.load_from_hdf(file_calibration) # pixel intensity calibration 1-255
ex_display = Display.load_from_hdf(
file_display
) # this is a grid representation of the screen (aruco marker calibration algorithm output)
ex_orientation = SpatialOrientation.load_from_hdf(file_orientation) # camera to display
ex_laptop_camera = Camera.load_from_hdf(file_laptop_camera)
# Phase 2: Load the sofast laptop measurement data
# (note that this data has already been collected for this opencsp example)
# =========================================================================
ex_measurement = MeasurementSofastFringe.load_from_hdf(file_measurement) # the sofast experimental data
# 2. Save projected sinusoidal fringe images to PNG format
# ========================================================
fringes = Fringes(ex_measurement.fringe_periods_x, ex_measurement.fringe_periods_y)
images = fringes.get_frames(
640, 320, 'uint8', [0, 255]
) # writes images we projected from laptop screen "projector" to disk
dir_save_cur = join(dir_save, '1_images_fringes_projected')
ft.create_directories_if_necessary(dir_save_cur)
# Save y images
for idx_image in range(ex_measurement.num_y_ims):
image = images[..., idx_image]
imageio.imwrite(join(dir_save_cur, f'y_{idx_image:02d}.png'), image)
# Save x images
for idx_image in range(ex_measurement.num_x_ims):
image = images[..., ex_measurement.num_y_ims + idx_image]
imageio.imwrite(join(dir_save_cur, f'x_{idx_image:02d}.png'), image)
# 3. Save captured sinusoidal fringe images and mask images to PNG format
# =======================================================================
dir_save_cur = join(dir_save, '2_images_captured')
ft.create_directories_if_necessary(dir_save_cur)
# Save mask (like a pixel mask value (all 0s, all 255s)) images
for idx_image in [0, 1]:
image = ex_measurement.mask_images[..., idx_image]
img_normalized = (image - image.min()) / (image.max() - image.min()) * 255
img_normalized = img_normalized.astype(np.uint8)
imageio.imwrite(join(dir_save_cur, f'mask_{idx_image:02d}.png'), img_normalized)
# Save y images (when lines were vertical, e.g.)
for idx_image in range(ex_measurement.num_y_ims):
image = ex_measurement.fringe_images_y[..., idx_image]
img_normalized = (image - image.min()) / (image.max() - image.min()) * 255
img_normalized = img_normalized.astype(np.uint8)
imageio.imwrite(join(dir_save_cur, f'y_{idx_image:02d}.png'), img_normalized)
# Save x images (when lines were horizontal, e.g.)
for idx_image in range(ex_measurement.num_x_ims):
image = ex_measurement.fringe_images_x[..., idx_image]
img_normalized = (image - image.min()) / (image.max() - image.min()) * 255
img_normalized = img_normalized.astype(np.uint8)
imageio.imwrite(join(dir_save_cur, f'x_{idx_image:02d}.png'), img_normalized)
# 4. Processes data with Sofast and save processed data to HDF5
# =============================================================
dir_save_cur = join(dir_save, '3_processed_data')
ft.create_directories_if_necessary(dir_save_cur)
# Define surface definition (parabolic surface), this is the mirror
surface = Surface2DParabolic(initial_focal_lengths_xy=(2.0, 2.0), robust_least_squares=False, downsample=5)
# Calibrate fringes - (aka sinosoidal image)
ex_measurement.calibrate_fringe_images(ex_calibration)
# Instantiate sofast object
sofast = Sofast(ex_measurement, ex_orientation, ex_laptop_camera, ex_display)
sofast.params.mask.keep_largest_area = True
# Process
sofast.process_optic_undefined(surface)
# Save processed data to HDF5 format
sofast.save_to_hdf(join(dir_save_cur, 'data_sofast_cosmetic_mirror_fringe.h5'))
# Save measurement statistics to JSON
config = SofastConfiguration()
config.load_sofast_object(sofast)
measurement_stats = config.get_measurement_stats()
# Save measurement stats as JSON
with open(join(dir_save_cur, 'cosmetic_mirror_measurement_statistics.json'), 'w', encoding='utf-8') as f:
json.dump(measurement_stats, f, indent=3)
# 5. Generate plot suite and save images files
# ============================================
dir_save_cur = join(dir_save, '4_processed_output_figures')
ft.create_directories_if_necessary(dir_save_cur)
# Get measured and reference optics
mirror_measured = sofast.get_optic('bilinear').mirror.no_parent_copy()
mirror_reference = MirrorParametric.generate_symmetric_paraboloid(0.55, mirror_measured.region)
# Define viewing/illumination geometry
# x and y is ground plane
# z is pointing up to the sky
# target is 100 meters up in air
v_target_center = Vxyz(
(0, 0, 0.55)
) # TODO: Update docs to specify meters, document that x is up, y is straight into air, and z is left-right
# TODO: try moving focal length out, etc.
# The normal is pointing down
v_target_normal = Vxyz((0, 0, -1))
# Pointing angle is pointing straight down (Uxyz(0,0,-1))
source = LightSourceSun.from_given_sun_position(Uxyz((0, 0, -1)), resolution=40)
# Save optic objects
plots = StandardPlotOutput()
plots.optic_measured = mirror_measured
plots.optic_reference = mirror_reference
# Update visualization parameters
plots.options_slope_vis.clim = 150 # maximum slope at edge of mirror (we know focal length and radius of mirror, )
plots.options_slope_vis.resolution = 0.001
plots.options_slope_vis.quiver_scale = 1200 # TODO: can this be set to auto and computed by default?
plots.options_slope_vis.quiver_density = 0.05 # TODO: can this be set to auto and computed by default?
plots.options_slope_deviation_vis.clim = 15
plots.options_slope_deviation_vis.resolution = 0.001
# TODO: Document why the quiver scale and denisty doesn't need to be updated. (Our magnitude of error is about 15 mrad, CSP mirrors are typically 7-10)
plots.options_curvature_vis.resolution = 0.001
plots.options_curvature_vis.clim = 50
plots.options_ray_trace_vis.enclosed_energy_max_semi_width = 1
plots.options_ray_trace_vis.hist_extent = 0.05 # image of light source reflection
plots.options_ray_trace_vis.hist_bin_res = 0.00075 # TODO: maybe also have a auto default to compute defaults
plots.options_ray_trace_vis.ray_trace_optic_res = 0.007 # TODO: maybe also have a auto default to compute defaults
plots.options_file_output.to_save = True
plots.options_file_output.number_in_name = False
plots.options_file_output.output_dir = dir_save_cur
# Define ray trace parameters
plots.params_ray_trace.source = source
plots.params_ray_trace.v_target_center = v_target_center
plots.params_ray_trace.v_target_normal = v_target_normal
# Create standard output plots
plots.plot()
# Create power point presentation
presentation = rcpp.RenderControlPowerpointPresentation()
slide_control = rcps.RenderControlPowerpointSlide()
images = [pi.PowerpointImage(join(dir_save_cur, "Slope_X_measured_xy.png"))]
texts = [pt.PowerpointText("slope x measured")]
slide = ps.PowerpointSlide(slide_control, images, texts)
> presentation.add_slide(slide)
example_laptop.py:257:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
../../opencsp/common/lib/render_control/RenderControlPowerpointPresentation.py:63: in add_slide
slide.save()
../../opencsp/common/lib/render/PowerpointSlide.py:354: in save
image.save()
../../opencsp/common/lib/render/lib/PowerpointImage.py:422: in save
saved_path, body_ext = self._save(image_path_name_ext)
../../opencsp/common/lib/render/lib/PowerpointImage.py:280: in _save
ft.copy_file(self._val, path_name_ext)
../../opencsp/common/lib/tool/file_tools.py:835: in copy_file
lt.error_and_raise(Contribution Guidelines
- I agree to follow this project's contribution guidelines
Metadata
Metadata
Assignees
Labels
No labels