Source code for wofryimpl.beamline.optical_elements.util.s4_optical_surface

"""
S4OpticalSurface — abstract base class for optical surface shapes used in wofryimpl mirror elements.
"""
# abstract class defining the interfaces of the optical surfaces to be implemented in the children classes
# it also defines common utilities
import numpy
import os
import h5py
import time



[docs] class S4OpticalSurface(object):
[docs] def info(self): raise NotImplementedError
[docs] def duplicate(self): raise NotImplementedError
[docs] def surface_height(self, x, y, **kwargs): raise NotImplementedError
[docs] def get_normal(self, x, **kwargs): raise NotImplementedError
[docs] def calculate_intercept(self, XIN, VIN, **kwargs): raise NotImplementedError
[docs] def apply_specular_reflection_on_beam(self, beam, **kwargs): raise NotImplementedError
[docs] def apply_refraction_on_beam(self, beam, **kwargs): raise NotImplementedError
[docs] def apply_crystal_diffraction_bragg_symmetric_on_beam(self, beam, **kwargs): raise NotImplementedError
# # common utilities #
[docs] def write_mesh_file(self, x, y, filename="surface.dat"): X = numpy.outer(x, numpy.ones_like(y)) Y = numpy.outer(numpy.ones_like(x), y) Z = self.surface_height(X, Y) write_shadow_surface(Z.T, x, y, outFile=filename)
[docs] def write_mesh_h5file(self, x, y, filename="surface.h5", subgroup_name="surface_file", overwrite=True): X = numpy.outer(x, numpy.ones_like(y)) Y = numpy.outer(numpy.ones_like(x), y) Z = self.surface_height(X, Y) if (os.path.isfile(filename)) and (overwrite == True): os.remove(filename) if not os.path.isfile(filename): # if file doesn't exist, create it. file = h5py.File(filename, 'w') # points to the default data to be plotted file.attrs['default'] = subgroup_name + '/Z' # give the HDF5 root some more attributes file.attrs['file_name'] = filename file.attrs['file_time'] = time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime()) file.attrs['creator'] = 'write_surface_file' file.attrs['code'] = 'Oasys' file.attrs['HDF5_Version'] = h5py.version.hdf5_version file.attrs['h5py_version'] = h5py.version.version file.close() file = h5py.File(filename, 'a') try: f1 = file.create_group(subgroup_name) except: f1 = file[subgroup_name] f1z = f1.create_dataset("Z", data=Z.T) f1x = f1.create_dataset("X", data=x) f1y = f1.create_dataset("Y", data=y) # NEXUS attributes for automatic plot f1.attrs['NX_class'] = 'NXdata' f1.attrs['signal'] = "Z" f1.attrs['axes'] = [b"Y", b"X"] f1z.attrs['interpretation'] = 'image' f1x.attrs['long_name'] = "X [m]" f1y.attrs['long_name'] = "Y [m]" file.close() print("File %s written to disk." % filename)
# copied from shadow3 ShadowTools
[docs] def write_shadow_surface(s, xx, yy, outFile='presurface.dat'): """ Write a 2-D height mesh to disk in the SHADOW *presurface* format. Parameters ---------- s : numpy.ndarray, shape (Nx, Ny) 2-D array of surface heights [m]. xx : numpy.ndarray, shape (Nx,) Spatial coordinates along the mirror width (sagittal axis) [m]. yy : numpy.ndarray, shape (Ny,) Spatial coordinates along the mirror length (tangential axis) [m]. outFile : str, optional Path to the output file. Default ``'presurface.dat'``. Returns ------- int 1 on success, 0 on failure. """ out = 1 try: fs = open(outFile, 'w') except IOError: out = 0 print("Error: can\'t open file: " + outFile) return else: # dimensions fs.write(repr(xx.size) + " " + repr(yy.size) + " \n") # y array for i in range(yy.size): fs.write(' ' + repr(yy[i])) fs.write("\n") # for each x element, the x value and the corresponding z(y) # profile for i in range(xx.size): tmps = "" for j in range(yy.size): tmps = tmps + " " + repr(s[j, i]) fs.write(' ' + repr(xx[i]) + " " + tmps) fs.write("\n") fs.close() print("write_shadow_surface: File for SHADOW " + outFile + " written to disk.")
if __name__ == "__main__": a = S4OpticalSurface() a.info()