def para_seqtrace( self, pilotbundle, initialbundle, elementsequence, pilotraypathsequence=None, use6x6=True ): # [("elem1", [1, 3, 4]), ("elem2", [1,4,4]), ("elem1", [4, 3, 1])] rpath = RayPath(initialbundle) pilotpath = RayPath(pilotbundle) if pilotraypathsequence is None: pilotraypathsequence = tuple( [0 for i in range(len(elementsequence))]) # choose first pilotray in every element by default print("pilot ray path sequence") print(pilotraypathsequence) for ((elem, subseq), prp_nr) in zip(elementsequence, pilotraypathsequence): (append_pilotpath, append_rpath) = self.elements[elem].para_seqtrace( pilotpath.raybundles[-1], rpath.raybundles[-1], subseq, self.material_background, pilotraypath_nr=prp_nr, use6x6=use6x6) rpath.appendRayPath(append_rpath) pilotpath.appendRayPath(append_pilotpath) return (pilotpath, rpath)
def seqtrace( self, initialbundle, elementsequence, splitup=False ): # [("elem1", [1, 3, 4]), ("elem2", [1,4,4]), ("elem1", [4, 3, 1])] rpath = RayPath(initialbundle) rpaths = [rpath] for (elem, subseq) in elementsequence: rpaths_new = [] for rp in rpaths: raypaths_to_append = self.elements[elem].seqtrace( rp.raybundles[-1], subseq, self.material_background, splitup=splitup) for rp_append in raypaths_to_append[1:]: rpathprime = deepcopy(rp) rpathprime.appendRayPath(rp_append) rpaths_new.append(rpathprime) rp.appendRayPath(raypaths_to_append[0]) rpaths = rpaths + rpaths_new return rpaths
def myPersonalMeritFunctionForTestingPurposes(s): """ This is a test Merit function for RMS of a finite corrected 20x microscope objective. The microscope sample is on the object side. Parfocal or tube length are not enforced. :param s: OpticalSystem object :return merit: merit function value (float) """ nray = 1E3 # number of rays rasterType = raster.RectGrid pupilType = pupil.ObjectSpaceNA pupilSizeParameter = 0.25 wavelengths = [0.48, 0.55, 0.65] stopPosition = 5 mag = 20 fieldType = field.ObjectHeight fieldpoints = 1. / mag * 0.5 * array([0., 17.5, 25.]) aimy = aim.aimFiniteByMakingASurfaceTheStop(s, pupilType, pupilSizeParameter, fieldType, rasterType, nray, wavelengths[1], stopPosition) # RMS at all field points merit_squared = 0 for wavelength in wavelengths: for y in fieldpoints: initialBundle = aimy.getInitialRayBundle(s, array([0., y]), wavelength) raypath_on_axis = RayPath(initialBundle, s) merit_squared += ( raypath_on_axis.raybundles[-1].getRMSspotSizeCentroid())**2 initialBundle = aimy.getInitialRayBundle(s, array([0., 0.]), wavelengths[1]) # magnification merit_squared += (s.getParaxialMagnification(initialBundle) - mag)**2 # positive thicknesses for i in arange(s.getNumberOfSurfaces()): merit_squared += (int(s.getThickness(i) < 0)) return merit_squared
def mySimpleDumbRMSSpotSizeMeritFunction(s): """ This is a test Merit function for RMS spot size on axis with modifications implemented suggested by Mo :param s: OpticalSystem object :return merit: merit function value (float) """ nray = 1e3 # number of rays rasterType = raster.RectGrid pupilType = pupil.StopDiameter # EntrancePupilDiameter pupilSizeParameter = 3.0 # 5.5 wavelength = 0.55 stopPosition = 5 fieldType = field.ObjectHeight fieldpoints = [0., 0.1, -0.1] aimy = aim.aimFiniteByMakingASurfaceTheStop(s, pupilType, pupilSizeParameter, fieldType, rasterType, nray, wavelength, stopPosition) # RMS at all field points merit_squared = 0 for y in fieldpoints: initialBundle = aimy.getInitialRayBundle(s, array([0., y]), wavelength) raypath_on_axis = RayPath(initialBundle, s) merit_squared += ( raypath_on_axis.raybundles[-1].getRMSspotSizeCentroid())**2 return merit_squared
def para_seqtrace(self, pilotbundle, raybundle, sequence, background_medium, pilotraypath_nr=0, use6x6=True): rpath = RayPath(raybundle) (pilotraypath, matrices) = self.calculateXYUV(pilotbundle, sequence, background_medium, pilotraypath_nr=pilotraypath_nr, use6x6=use6x6) (hitlist, optionshitlistdict) = self.sequence_to_hitlist(sequence) for (ps, pe, surfhit) in zip(pilotraypath.raybundles[:-1], pilotraypath.raybundles[1:], hitlist): (surf_start_key, surf_end_key, hit) = surfhit surf_start = self.__surfaces[surf_start_key] surf_end = self.__surfaces[surf_end_key] x0_glob = rpath.raybundles[-1].x[-1] k0_glob = rpath.raybundles[-1].k[-1] newbundle = RayBundle(x0_glob, k0_glob, None, rpath.raybundles[-1].rayID, wave=rpath.raybundles[-1].wave) x0 = surf_start.rootcoordinatesystem.returnGlobalToLocalPoints(x0_glob) k0 = surf_start.rootcoordinatesystem.returnGlobalToLocalDirections(k0_glob) px0 = surf_start.rootcoordinatesystem.returnGlobalToLocalPoints(ps.x[-1][:, 0].reshape((3, 1))) pk0 = surf_start.rootcoordinatesystem.returnGlobalToLocalDirections(ps.k[-1][:, 0].reshape((3, 1))) px1 = surf_end.rootcoordinatesystem.returnGlobalToLocalPoints(pe.x[-1][:, 0].reshape((3, 1))) pk1 = surf_end.rootcoordinatesystem.returnGlobalToLocalDirections(pe.k[-1][:, 0].reshape((3, 1))) dx0 = (x0 - px0)[0:2] if use6x6: dk0_real = (k0 - pk0)[0:2].real dk0_imag = (k0 - pk0)[0:2].imag DX0 = np.vstack((dx0, dk0_real, dk0_imag)) else: dk0 = (k0 - pk0)[0:2] DX0 = np.vstack((dx0, dk0)) DX1 = np.dot(matrices[surfhit], DX0) # multiplication is somewhat contra-intuitive # Xend = M("surf2", "surf3", 1) M("surf1", "surf2", 1) X0 dx1 = DX1[0:2] if use6x6: dk1 = DX1[2:4] + complex(0, 1)*DX1[4:6] else: dk1 = DX1[2:4] (num_dims, num_pts) = np.shape(dx1) dx1 = np.vstack((dx1, np.zeros(num_pts, dtype=complex))) dk1 = np.vstack((dk1, np.zeros(num_pts, dtype=complex))) x1 = surf_end.rootcoordinatesystem.returnLocalToGlobalPoints(dx1 + px1) k1 = surf_end.rootcoordinatesystem.returnLocalToGlobalDirections(dk1 + pk1) newbundle.append(x1, k1, newbundle.Efield[0], np.ones(num_pts, dtype=bool)) #surf_end.intersect(newbundle) # FIXME: leads to changes in the linearized raybundles due to modifications # at the surface boundaries; we have to perform the aperture check ourselves rpath.appendRayBundle(newbundle) return (pilotraypath, rpath)
def seqtrace(self, raybundle, sequence, background_medium, splitup=False): # FIXME: should depend on a list of RayPath current_material = background_medium rpath = RayPath(raybundle) rpaths = [rpath] # surfoptions is intended to be a comma separated list # of keyword=value pairs for (surfkey, surfoptions) in sequence: refract_flag = not surfoptions.get("is_mirror", False) # old: current_bundle = rpath.raybundles[-1] # old: current_material.propagate(current_bundle, current_surface) rpaths_new = [] current_surface = self.__surfaces[surfkey] (mnmat, pnmat) = self.__surf_mat_connection[surfkey] mnmat = self.__materials.get(mnmat, background_medium) pnmat = self.__materials.get(pnmat, background_medium) # finalize current_bundles for rp in rpaths: current_bundle = rp.raybundles[-1] current_material.propagate(current_bundle, current_surface) # TODO: remove code doubling if refract_flag: # old: current_material = self.findoutWhichMaterial(mnmat, pnmat, current_material) # old: rpath.appendRayBundle(current_material.refract(current_bundle, current_surface)) # old: finish current_material = self.findoutWhichMaterial(mnmat, pnmat, current_material) for rp in rpaths: current_bundle = rp.raybundles[-1] raybundles = current_material.refract(current_bundle, current_surface, splitup=splitup) for rb in raybundles[1:]: # if there are more than one return value, copy path rpathprime = deepcopy(rp) rpathprime.appendRayBundle(rb) rpaths_new.append(rpathprime) rp.appendRayBundle(raybundles[0]) else: # old: rpath.appendRayBundle(current_material.reflect(current_bundle, current_surface)) # old: finish for rp in rpaths: current_bundle = rp.raybundles[-1] raybundles = current_material.reflect(current_bundle, current_surface, splitup=splitup) for rb in raybundles[1:]: rpathprime = deepcopy(rp) rpathprime.appendRayBundle(rb) rpaths_new.append(rpathprime) rp.appendRayBundle(raybundles[0]) rpaths = rpaths + rpaths_new return rpaths
def extractXYUV(self, pilotbundle, elementsequence, pilotraypathsequence=None, use6x6=True): pilotpath = RayPath(pilotbundle) if pilotraypathsequence is None: pilotraypathsequence = tuple([0 for i in range(len(elementsequence))]) # choose first pilotray in every element by default print("pilot ray path sequence") print(pilotraypathsequence) stops_found = 0 for (elem, subseq) in elementsequence: for (surfname, options_dict) in subseq: if options_dict.get("is_stop", False): stops_found += 1 if stops_found != 1: print("WARNING: %d stops found. need exactly 1!" % (stops_found,)) print("Returning None.") return None lst_matrix_pairs = [] for ((elem, subseq), prp_nr) in zip(elementsequence, pilotraypathsequence): #print(subseq) (hitlist, optionshitlist_dict) = self.elements[elem].sequence_to_hitlist(subseq) # hitlist may contain exactly one stophit (append_pilotpath, elem_matrices) = self.elements[elem].calculateXYUV(pilotpath.raybundles[-1], subseq, self.material_background, pilotraypath_nr=prp_nr, use6x6=use6x6) pilotpath.appendRayPath(append_pilotpath) ls1 = [] ls2 = [] found_stop = False for h in hitlist: (d1, d2) = optionshitlist_dict[h] if d1.get("is_stop", False) and not d2.get("is_stop", False): found_stop = True if not found_stop: ls1.append(elem_matrices[h]) else: ls2.append(elem_matrices[h]) if not use6x6: m1 = np.eye(4, dtype=complex) m2 = np.eye(4, dtype=complex) else: m1 = np.eye(6) m2 = np.eye(6) for m in ls1: m1 = np.dot(m, m1) for m in ls2: m2 = np.dot(m, m2) lst_matrix_pairs.append((m1, m2, found_stop)) if not use6x6: m_obj_stop = np.eye(4, dtype=complex) m_stop_img = np.eye(4, dtype=complex) else: m_obj_stop = np.eye(6) m_stop_img = np.eye(6) obj_stop_branch = True for (m1, m2, found_stop) in lst_matrix_pairs: if obj_stop_branch: m_obj_stop = np.dot(m1, m_obj_stop) if found_stop: m_stop_img = np.dot(m2, m_stop_img) obj_stop_branch = False else: m_stop_img = np.dot(m1, m_stop_img) return (m_obj_stop, m_stop_img)