def __init__(self, point, direction, parent=None, name=""): if not isinstance(point, Point3D): raise TypeError( "point argument for SpectroscopicSightLine must be of type Point3D." ) if not isinstance(direction, Vector3D): raise TypeError( "direction argument for SpectroscopicSightLine must be of type Vector3D." ) self._point = Point3D(0, 0, 0) self._direction = Vector3D(1, 0, 0) self._transform = AffineMatrix3D() self._spectral_pipeline = SpectralRadiancePipeline0D(accumulate=False) # TODO - carry over wavelength range and resolution settings self._observer = SightLine(pipelines=[self._spectral_pipeline], parent=parent, name=name) self.name = name self.point = point self.direction = direction
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
class SpectroscopicSightLine: """ A simple line of sight observer. Fires a single ray oriented along the observer's z axis in world space. :param Point3D point: The observation point for this sight-line. :param Vector3D direction: The observation direction for this sight-line. """ def __init__(self, point, direction, parent=None, name=""): if not isinstance(point, Point3D): raise TypeError( "point argument for SpectroscopicSightLine must be of type Point3D." ) if not isinstance(direction, Vector3D): raise TypeError( "direction argument for SpectroscopicSightLine must be of type Vector3D." ) self._point = Point3D(0, 0, 0) self._direction = Vector3D(1, 0, 0) self._transform = AffineMatrix3D() self._spectral_pipeline = SpectralRadiancePipeline0D(accumulate=False) # TODO - carry over wavelength range and resolution settings self._observer = SightLine(pipelines=[self._spectral_pipeline], parent=parent, name=name) self.name = name self.point = point self.direction = direction @property def point(self): return self._point @point.setter def point(self, value): if not (self._direction.x == 0 and self._direction.y == 0 and self._direction.z == 1): up = Vector3D(0, 0, 1) else: up = Vector3D(1, 0, 0) self._point = value self._observer.transform = translate( value.x, value.y, value.z) * rotate_basis(self._direction, up) @property def direction(self): return self._direction @direction.setter def direction(self, value): if value.x != 0 and value.y != 0 and value.z != 1: up = Vector3D(0, 0, 1) else: up = Vector3D(1, 0, 0) self._direction = value self._observer.transform = translate(self._point.x, self._point.y, self._point.z) * rotate_basis( value, up) @property def min_wavelength(self): return self._observer.min_wavelength @min_wavelength.setter def min_wavelength(self, value): self._observer.min_wavelength = value @property def max_wavelength(self): return self._observer.max_wavelength @max_wavelength.setter def max_wavelength(self, value): self._observer.max_wavelength = value @property def spectral_bins(self): return self._observer.spectral_bins @spectral_bins.setter def spectral_bins(self, value): self._observer.spectral_bins = value @property def observed_spectrum(self): # TODO - throw exception if no observed spectrum pipeline = self._spectral_pipeline spectrum = Spectrum(pipeline.min_wavelength, pipeline.max_wavelength, pipeline.bins) spectrum.samples = pipeline.samples.mean return spectrum def observe(self): """ Ask this sight-line to observe its world. """ self._observer.observe() def plot_spectra(self, unit='J', ymax=None, extras=True): """ Plot the observed spectrum. """ if unit == 'J': # Spectrum objects are already in J/s/m2/str/nm spectrum = self.observed_spectrum elif unit == 'ph': # turn the samples into ph/s/m2/str/nm spectrum = self.observed_spectrum.new_spectrum() spectrum.samples = self.observed_spectrum.to_photons() else: raise ValueError("unit must be 'J' or 'ph'.") plt.plot(spectrum.wavelengths, spectrum.samples) if extras: if ymax is not None: plt.ylim(ymax=ymax) plt.title(self.name) plt.xlabel('wavelength (nm)') plt.ylabel('radiance ({}/s/m^2/str/nm)'.format(unit))
plt.plot(z, beam_half_densities, label="half energy") plt.xlabel('z axis (beam coords)') plt.ylabel('beam component density [m^-3]') plt.title("Beam attenuation by energy component") plt.legend() # OBSERVATIONS ---------------------------------------------------------------- camera = PinholeCamera((128, 128), parent=world, transform=translate(1.25, -3.5, 0) * rotate_basis(Vector3D(0, 1, 0), Vector3D(0, 0, 1))) camera.spectral_rays = 1 camera.spectral_bins = 15 camera.pixel_samples = 5 # turning off parallisation because this causes issues with the way RENATE currently loads atomic data from raysect.core.workflow import SerialEngine camera.render_engine = SerialEngine() plt.ion() camera.observe() power = PowerPipeline0D(accumulate=False) spectral_power = SpectralPowerPipeline0D() los = SightLine(pipelines=[power, spectral_power], min_wavelength=640, max_wavelength=665, parent=world, transform=translate(*los_start) * rotate_basis(los_direction, Vector3D(0, 0, 1))) los.pixel_samples = 1 los.spectral_bins = 2000 los.observe() plt.ioff() plt.show()