def as_sightline(self): """ Constructs a SightLine observer for this bolometer. :rtype: SightLine """ if self.units == "Power": pipeline = PowerPipeline0D(accumulate=False) elif self.units == "Radiance": pipeline = RadiancePipeline0D(accumulate=False) else: raise ValueError( "The units argument of BolometerFoil must be one of 'Power' or 'Radiance'." ) los_observer = SightLine(pipelines=[pipeline], pixel_samples=1, quiet=True, parent=self, name=self.name) los_observer.render_engine = self.render_engine los_observer.spectral_bins = self.spectral_bins los_observer.min_wavelength = self.min_wavelength los_observer.max_wavelength = self.max_wavelength return los_observer
def load_dms_output(config, world, plasma, spec, fibgeom): from raysect.optical.observer import FibreOptic, PowerPipeline0D, SpectralRadiancePipeline0D from raysect.optical import translate, rotate, rotate_basis from raysect.core import Vector3D, Point3D power_arr = np.zeros(fibgeom.numfibres) spectra_arr = np.zeros((spec.pixels, fibgeom.numfibres)) for i, f in enumerate(power_arr): print("Analysing fibre: ", int(i + 1)) fibgeom.set_fibre(number=int(i + 1)) start_point = Point3D(fibgeom.origin[0], fibgeom.origin[1], fibgeom.origin[2]) forward_vector = Vector3D(fibgeom.xhat(), fibgeom.yhat(), fibgeom.zhat()).normalise() up_vector = Vector3D(0, 0, 1.0) if config['dms']['power_pipeline']: power = PowerPipeline0D() fibre = FibreOptic([power], acceptance_angle=1, radius=0.001, spectral_bins=spec.pixels, spectral_rays=1, pixel_samples=5, transform=translate(*start_point) * rotate_basis(forward_vector, up_vector), parent=world) fibre.min_wavelength = spec.wlower fibre.max_wavelength = spec.wupper fibre.observe() power_arr[i] = power.value.mean else: power_arr[i] = None if config['dms']['radiance_pipeline']: spectra = SpectralRadiancePipeline0D(display_progress=False) fibre = FibreOptic([spectra], acceptance_angle=1, radius=0.001, spectral_bins=spec.pixels, spectral_rays=1, pixel_samples=5, transform=translate(*start_point) * rotate_basis(forward_vector, up_vector), parent=world) fibre.min_wavelength = spec.wlower fibre.max_wavelength = spec.wupper fibre.observe() spectra_arr[:, i] = spectra.samples.mean else: spectra_arr[:, i] = None return power_arr, spectra_arr
sphere_radius = 0.5 cube_size = 2 min_wl = 400 max_wl = 401 # sanity check! if cube_size <= 2 * sphere_radius: raise ValueError("The cube dimensions must be larger that the sphere.") # set-up scenegraph world = World() emitter = Sphere(radius=sphere_radius, parent=world) # The observer plane covers 1 side of a cube - to work out total power, multiply result by 6 power = PowerPipeline0D(accumulate=False) observing_plane = Pixel([power], x_width=cube_size, y_width=cube_size, min_wavelength=min_wl, max_wavelength=max_wl, spectral_bins=1, pixel_samples=samples, parent=world, transform=rotate(0, 0, 0) * translate(0, 0, -cube_size / 2)) # Emitter is a sphere volume emitter located at the origin # Volume of the sphere is 4/3 * Pi * r^3, emission over 4 * pi # UnityVolumeEmitter emits 1W/str/m^3/ x nm, where x is the wavelength interval, integrated over length
def add_isttok(self, pixel_samples=1000000): nickel_roughness = 0.23 min_wl = 50 max_wl = 51 # add vessel and cameras self.vessel = import_stl( "../isttok_3d/vessel5_stl.stl", scaling=1, mode='binary', parent=self.world, material=RoughNickel(nickel_roughness), #AbsorbingSurface(), transform=translate(0, 0, 0) * rotate(0, 0, 0)) self.camera_top = import_stl( "../isttok_3d/camera_top3_stl.stl", scaling=1, mode='binary', parent=self.world, material=AbsorbingSurface(), transform=translate( self.x_shift_top, self.y_shift_top + self.tube_height + self.lid_top, self.vessel_width / 2.0) * rotate(0, -90, 0)) # self.camera_outer = import_stl("../isttok_3d/camera_outer3_stl.stl", scaling=1, mode='binary', parent=self.world, # material=AbsorbingSurface(), # transform=translate(self.x_shift_outer - self.tube_height - self.lid_outer, # 0.0, # self.vessel_width / 2.0) * rotate(-90, 0, 0)) self.camera_outer = import_stl( "../isttok_3d/camera_outer4_newpin_stl.stl", scaling=1, mode='binary', parent=self.world, material=AbsorbingSurface(), transform=translate( self.x_shift_outer - self.tube_height - self.lid_outer, 0.0, self.vessel_width / 2.0) * rotate(-90, 0, 0)) pinhole_sphere_radius = 0.0005 # 0.0005 self.top_pinhole = Sphere(radius=pinhole_sphere_radius, parent=self.world, transform=translate(self.x_shift_top, self.y_shift_top, self.vessel_width / 2), material=Vacuum()) pinhole_sphere_radius = 0.00035 # 0.0005 self.out_pinhole = Sphere(radius=pinhole_sphere_radius, parent=self.world, transform=translate(self.x_shift_outer, 0.0, self.vessel_width / 2), material=Vacuum()) for i in range(16): self.top_power.append(PowerPipeline0D(accumulate=False)) self.out_power.append(PowerPipeline0D(accumulate=False)) top_px_x = self.top_px_first_x - i * 0.00095 top_px_y = self.top_px_first_y - i * 2 * (self.top_twist / 15) top_angle = degrees(asin(2 * self.top_twist / 0.01425)) out_px_y = self.out_px_first_y - i * 0.00095 out_px_x = self.out_px_first_x - i * 2 * (self.out_twist / 15) out_angle = -degrees(asin(2 * self.out_twist / 0.01425)) self.top_px.append( TargettedPixel( targets=[self.top_pinhole], targetted_path_prob=1.0, pipelines=[self.top_power[i]], x_width=0.00075, y_width=0.00405, min_wavelength=min_wl, max_wavelength=max_wl, spectral_bins=1, pixel_samples=pixel_samples, parent=self.world, quiet=True, ray_importance_sampling=True, ray_important_path_weight=0.05, ray_max_depth=50, transform=translate(top_px_x, top_px_y, self.top_px_z) * rotate(0, 0, top_angle) * rotate(0, -90, 0))) self.out_px.append( TargettedPixel( targets=[self.out_pinhole], targetted_path_prob=1.0, pipelines=[self.out_power[i]], x_width=0.00075, y_width=0.00405, min_wavelength=min_wl, max_wavelength=max_wl, spectral_bins=1, pixel_samples=pixel_samples, parent=self.world, quiet=True, ray_importance_sampling=True, ray_important_path_weight=0.05, ray_max_depth=50, transform=translate(out_px_x, out_px_y, self.out_px_z) * rotate(0, 0, out_angle) * rotate(-90, 0, 90)))
def __init__(self, detector_id, centre_point, basis_x, dx, basis_y, dy, slit, parent=None, units="Power", accumulate=False, curvature_radius=0): # perform validation of input parameters if not isinstance(dx, (float, int)): raise TypeError("dx argument for BolometerFoil must be of type float/int.") if not dx > 0: raise ValueError("dx argument for BolometerFoil must be greater than zero.") if not isinstance(dy, (float, int)): raise TypeError("dy argument for BolometerFoil must be of type float/int.") if not dy > 0: raise ValueError("dy argument for BolometerFoil must be greater than zero.") if not isinstance(slit, BolometerSlit): raise TypeError("slit argument for BolometerFoil must be of type BolometerSlit.") if not isinstance(centre_point, Point3D): raise TypeError("centre_point argument for BolometerFoil must be of type Point3D.") if not isinstance(curvature_radius, (float, int)): raise TypeError("curvature_radius argument for BolometerFoil " "must be of type float/int.") if curvature_radius < 0: raise ValueError("curvature_radius argument for BolometerFoil " "must not be negative.") if not isinstance(basis_x, Vector3D): raise TypeError("The basis vectors of BolometerFoil must be of type Vector3D.") if not isinstance(basis_y, Vector3D): raise TypeError("The basis vectors of BolometerFoil must be of type Vector3D.") self._centre_point = centre_point self._basis_x = basis_x.normalise() self._basis_y = basis_y.normalise() self._normal_vec = self._basis_x.cross(self._basis_y) self._slit = slit self._foil_to_slit_vec = self._centre_point.vector_to(self._slit.centre_point).normalise() self._curvature_radius = curvature_radius self.units = units # setup root bolometer foil transform translation = translate(self._centre_point.x, self._centre_point.y, self._centre_point.z) rotation = rotate_basis(self._normal_vec, self._basis_y) if self.units == "Power": pipeline = PowerPipeline0D(accumulate=accumulate) elif self.units == "Radiance": pipeline = RadiancePipeline0D(accumulate=accumulate) else: raise ValueError("The units argument of BolometerFoil must be one of 'Power' or 'Radiance'.") super().__init__([slit.target], targetted_path_prob=1.0, pipelines=[pipeline], pixel_samples=1000, x_width=dx, y_width=dy, spectral_bins=1, quiet=True, parent=parent, transform=translation * rotation, name=detector_id) # round off the detector corners, if applicable if self._curvature_radius > 0: mask_corners(self)
material=schott("N-BK7")) # 2. Build Scenegraph # ------------------- world = World() sphere.parent = world ground.parent = world emitter.parent = world # 3. Add Observer # --------------- spectra = SpectralPowerPipeline0D() power = PowerPipeline0D() fibre = FibreOptic([spectra, power], acceptance_angle=2, radius=0.001, transform=translate(0, 0, -5), parent=world) fibre.spectral_bins = 500 fibre.spectral_rays = 1 fibre.pixel_samples = pixel_samples = 1000 # 4. Observe() # ------------ plt.ion() fibre.observe()
# # create a small emitting box, simulating a 1x10 mm slit 100 mm from a 10x10 mm pixel surface, 20mm off axis # emitter = Box(Point3D(-0.005, -0.0005, -0.0005), Point3D(0.005, 0.0005, 0.0005), world, translate(0.02, 0, 0.10), UnitySurfaceEmitter()) # targets = [emitter] # create a small emitting box, same as above, but split into 10 1x1x1mm cubes so that the bounding spheres are a tighter fit to the slit. emitter = Node(parent=world, transform=translate(0.02, 0, 0.10)) targets = [] for i in range(10): section = Box(Point3D(-0.0005, -0.0005, -0.0005), Point3D(0.0005, 0.0005, 0.0005), emitter, translate(0.001 * i - 0.0045, 0, 0), UnitySurfaceEmitter()) targets.append(section) # setup basic pixel basic_pipeline = PowerPipeline0D(name="Basic Pixel Observer") basic_pixel = Pixel(parent=world, pixel_samples=SAMPLES, pipelines=[basic_pipeline]) # setup targetted pixel targetted_pipeline = PowerPipeline0D(name="Targeted Pixel Observer") targetted_pixel = TargettedPixel(parent=world, targets=targets, pixel_samples=SAMPLES, pipelines=[targetted_pipeline]) targetted_pixel.targetted_path_prob = 1 # render ion() basic_pixel.observe()
cherab_total_power = 0 start = time.time() for i, detector in enumerate(aug_wall_detectors): print() print("detector {}".format(i)) y_width = detector[2] centre_point = detector[3] normal_vector = detector[4] y_vector = detector[5] pixel_area = X_WIDTH * y_width power_data = PowerPipeline0D() pixel_transform = translate(centre_point.x, centre_point.y, centre_point.z) * rotate_basis( normal_vector, y_vector) pixel = Pixel([power_data], x_width=X_WIDTH, y_width=y_width, name='pixel-{}'.format(i), spectral_bins=1, transform=pixel_transform, parent=world, pixel_samples=500) pixel.observe()