10.4. Observers¶

Most plasma diagnostics can be easily modelled using the base observer types provided in Raysect. In Cherab we only provide a few specialist observers with extra functionality.

10.4.1. Bolometers¶

Bolometer systems are modelled as a collection of foils viewing emission through a collection of apertures. The foils and slits are grouped together into a BolometerCamera object, which acts as the parent node for the apertures and detectors. Bolometer cameras contain one or more slits (apertures), which provide targetting information for the foils (detectors) to improve computational efficiency. Bolometer cameras also contain one or more foils, which are modelled as pixels and which fire rays in the direction of the slit.

A note on units: the BolometerFoil class can be used to measure emission in units of power [W] or radiance [W/m²/sr]. In the latter case, the radiance is defined as the mean radiance over the entire solid angle $$\Omega = 2 \pi$$ subtended by the foil:

$\begin{split}\overline{L} &= \frac{\Phi}{A \Omega} \\ \Phi &= \int_0^{\Omega} \mathrm{d}\omega \int_0^A \mathrm{d}A \, L(\mathbf{x}, \omega) \cos(\theta)\end{split}$

When a bolometer is approximated by a single line of sight, the radiance measured is taken at a single angle and position: it is equivalent to the above equations in the limits $$\Omega \to 0$$ and $$A \to 0$$. A real bolometer needs some finite area and solid angle to measure signal, and as long as the solid angle $$\omega_s$$ subtended by the slit at the foil surface is small, a meaningful comparison to a sightline can be made using:

$\begin{split}L_B &= \frac{\Phi_B}{A \omega_s} \\ \Phi_B &= \int_0^{\omega_s} \mathrm{d}\omega \int_0^A \mathrm{d}A \, L(\mathbf{x}, \omega) \cos(\theta)\end{split}$

Note that $$\Phi_B = \Phi$$, since no power is incident on the bolometer for solid angles $$\omega > \omega_s$$, and this allows us to directly relate the radiance reported by Cherab with the radiance expected from a finite bolometer system being modelled as a sightline:

$\frac{L_B}{\overline{L}} = \frac{\omega_s}{\Omega}$

When comparing radiance measurements from Cherab with other modelling tools which treat the bolometer as a single sightline, applying this conversion factor is necessary. The fractional solid angle can be easily determined from the bolometer etendue $$G$$, which is given by:

$G = A \omega_s = A \Omega \frac{\omega_s}{\Omega}.$

CHERAB also provides an Infra-Red Video Bolometer (IRVB) class. These are typically large foil bolometers which are imaged with an IR camera. CHERAB models only the incoming radiation incident on the foil, not the subsequent IR emission on the IR camera-facing side of the foil: solving the heat transfer equation to calculate this is left to downstream codes.

Practically, the IRVB foil is typically divided up into separate regions, and the incident power on each of these individual regions is the quantity of interest. The foil can then be treated as a 2D array of pixels, where each pixel corresponds to a separate region on the foil. In this sense, the IRVB is used in a similar manner to a CCD array: observations will return a 2D array of measured powers. The pixels the foil is divided into are specified at instantiation time, along with the width of the foil: the height is calculated from the width and the pixel dimensions.

Although the IRVB observations produce data similar to that of a CCD array, instantiation of the BolometerIRVB is done in much the same way as for the BolometerFoil. The two have similar methods too, with the caveat that some methods of the BolometerIRVB return 2D arrays in place of a single return value for the BolometerFoil.

class cherab.tools.observers.bolometry.BolometerCamera(camera_geometry=None, parent=None, transform=None, name='')

A group of bolometer sight-lines under a single scenegraph node.

A scenegraph object that manages a collection of BolometerFoil objects. Allows combined observation and display control simultaneously.

Parameters
• camera_geometry (Primitive) – A Raysect primitive to supply as the box/aperture geometry.

• parent (Node) – The parent node of this camera in the scenegraph, often an optical World object.

• transform (AffineMatrix3D) – The relative coordinate transform of this bolometer camera relative to the parent.

• name (str) – The name for this bolometer camera.

Variables
• foil_detectors (list) – A list of the foil detector objects that belong to this camera.

• slits (list) – A list of the bolometer slit objects that belong to this camera.

>>> from raysect.optical import World
>>> from cherab.tools.observers import BolometerCamera
>>>
>>> world = World()
>>> camera = BolometerCamera(name="MyBolometer", parent=world)
__getitem__(item)

Returns the detectors by integer index or the detector name.

>>> detector_2 = bolometer_camera
>>> detector_a = bolometer_camera["detector_a"]
__iter__()

Iterates over the foil detectors in this camera.

>>> detector_a, detector_b, detector_c = bolometer_camera
__len__()

Yields the number of detectors in this bolometer camera.

Add the given detector to this camera.

Parameters

foil_detector ((BolometerFoil, BolometerIRVB)) – An instanced bolometer foil detector.

observe()

Take an observation with this camera.

Calls observe() on each foil detector and returns their power measurements.

class cherab.tools.observers.bolometry.BolometerSlit(slit_id, centre_point, basis_x, dx, basis_y, dy, dz=0.001, parent=None, csg_aperture=False, curvature_radius=0)

A rectangular bolometer slit.

A single slit can be shared by multiple detectors in the parent camera. The slit geometry is specified in terms of its centre_point, basis vectors in the plane of the slit and their respective lengths. When instantiating a BolometerSlit object these values are defined in the local coordinate system of the slit’s parent, usually a BolometerCamera object. Accessing these properties on an existing BolometerSlit object returns them in the world’s coordinate system.

If an external mesh model has been loaded for ray occlusion evaluation then this object is only used for targeting rays on the slit. If no mesh has been supplied, this object can construct an effective slit primitive from CSG operations.

Warning

Be very careful when using a CSG aperture. The aperture geometry is slightly larger than the slit dx and dy, which can cause partial occlusion of nearby primitives. It also relies on no rays being launched with directions outside the solid angle of the aperture’s bounding sphere: depending on the foil-slit distance and slit size, and also the foil’s targetted_path_prob, this may not be guaranteed. Supplying a proper mesh geometry for the camera is recommended instead of using a CSG aperture.

Parameters
• slit_id (str) – The name for this slit.

• centre_point (Point3D) – The centre point of the slit.

• basis_x (Vector3D) – The x basis vector for the slit.

• dx (float) – The width of the slit along the x basis vector.

• basis_y (Vector3D) – The y basis vector for the slit.

• dy (float) – The height of the slit along the y basis vector.

• dz (float) – The thickness of the slit along the z basis vector.

• parent (Node) – The parent scenegraph node to which this slit belongs. Typically a BolometerCamera or an optical World object.

• csg_aperture (bool) – Toggles whether an occluding surface should be constructed for this slit using CSG operations.

• curvature_radius (float) – Slits in real bolometer cameras may have curved corners due to machining limitations. This parameter species the corner radius.

Variables

normal_vector (Vector3D) – The normal vector of the slit constructed from the cross product of the x and y basis vectors.

>>> from raysect.core import Point3D, Vector3D
>>> from raysect.optical import World
>>> from cherab.tools.observers import BolometerSlit
>>>
>>> world = World()
>>>
>>> # construct basis vectors
>>> basis_x = Vector3D(1, 0, 0)
>>> basis_y = Vector3D(0, 1, 0)
>>> basis_z = Vector3D(0, 0, 1)
>>>
>>> # specify the slit
>>> dx = 0.0025
>>> dy = 0.005
>>> centre_point = Point3D(0, 0, 0)
>>> slit = BolometerSlit("slit", centre_point, basis_x, dx, basis_y, dy, parent=camera)
class cherab.tools.observers.bolometry.BolometerFoil(detector_id, centre_point, basis_x, dx, basis_y, dy, slit, parent=None, units='Power', accumulate=False, curvature_radius=0)

A rectangular foil bolometer detector.

When instantiating a detector, the position and orientation (i.e. centre_point, basis_x and basis_y) are given in the local coordinate system of the foil’s parent, usually a BolometerCamera instance. When these properties are accessed after instantiation, they are given in the coordinate system of the world.

Parameters
• detector_id (str) – The name for this detector.

• centre_point (Point3D) – The centre point of the detector.

• basis_x (Vector3D) – The x basis vector for the detector.

• dx (float) – The width of the detector along the x basis vector.

• basis_y (Vector3D) – The y basis vector for the detector.

• dy (float) – The height of the detector along the y basis vector.

• parent (Node) – The parent scenegraph node to which this detector belongs. Typically a BolometerCamera or an optical World object.

• units (str) – The units in which to perform observations, can be [‘Power’, ‘Radiance’].

• accumulate (bool) – Whether this observer should accumulate samples with multiple calls to observe.

• curvature_radius (float) – Detectors in real bolometer cameras typically have curved corners due to machining limitations. This parameter species the corner radius.

Variables
• normal_vector (Vector3D) – The normal vector of the detector constructed from the cross product of the x and y basis vectors.

• sightline_vector (Vector3D) – The vector that points from the centre of the foil detector to the centre of the slit. Defines the effective sightline vector of the detector.

>>> from raysect.core import Point3D, Vector3D
>>> from raysect.optical import World
>>> from cherab.tools.observers import BolometerFoil
>>>
>>> world = World()
>>>
>>> # construct basis vectors
>>> basis_x = Vector3D(1, 0, 0)
>>> basis_y = Vector3D(0, 1, 0)
>>> basis_z = Vector3D(0, 0, 1)
>>>
>>> # specify a detector, you need already created slit and camera objects
>>> dx = 0.0025
>>> dy = 0.005
>>> centre_point = Point3D(0, 0, -0.08)
>>> detector = BolometerFoil("ch#1", centre_point, basis_x, dx, basis_y, dy, slit, parent=camera)
as_sightline()

Constructs a SightLine observer for this bolometer.

Return type

SightLine

calculate_etendue(ray_count=10000, batches=10, max_distance=inf)

Calculates the etendue of this detector.

This function calculates the detectors etendue by evaluating the fraction of rays that pass un-impeded through the detector’s aperture.

Parameters
• ray_count (int) – The number of rays used per batch.

• batches (int) – The number of batches used to estimate the error on the etendue calculation.

• max_distance (float) – The maximum distance from the detector to consider intersections. If a ray makes it further than this, it is assumed to have passed through the aperture, regardless of what it hits. Use this if there are other primitives present in the scene which do not form the aperture.

Returns

A tuple (etendue, etendue_error).

calculate_sensitivity(voxel_collection, ray_count=10000)

Calculates a sensitivity vector for this detector on the specified voxel collection.

This function is used for calculating sensitivity matrices which can be combined for multiple detectors into a sensitivity matrix $$\mathbf{W}$$. If the BolometerFoil has units of “Power”, the returned sensitivity matrix has units of [m³ sr]. If the BolometerFoil has units of “Radiance”, the returned sensitivity matrix has units of [m sr].

Parameters
• voxel_collection (VoxelCollection) – The voxel collection on which to calculate the sensitivities.

• ray_count (int) – The number of rays to use in the calculation. This should be at least >= 10000 for decent statistics.

Returns

A 1D array of sensitivities with length equal to the number of voxels in the collection.

trace_sightline()

Traces the central sightline through the detector to see where the sightline terminates.

Raises a RuntimeError exception if no intersection was found.

Returns

A tuple containing the origin point, hit point and terminating surface primitive.

class cherab.tools.observers.bolometry.BolometerIRVB(name, width, pixels, slit, transform, parent=None, units='power', accumulate=False, curvature_radius=0)

A rectangular infra red video bolometer (IRVB).

Can be configured to sample a single ray per pixel, or fan of rays oriented along the observer’s z axis.

Parameters
• name (str) – The name for this detector.

• width (float) – The width of the detector along the x basis vector.

• pixels (tuple) – The number of pixels to divide the foil into. Pixels are square, so the height of the foil is determined by the width of the foil and the number of rows and columns of pixels.

• slit (BolometerSlit) – The slit the IRVB views through.

• transform (AffineMatrix3D) – The foil’s transform relative to its parent.

• parent (Node) – The parent scenegraph node to which this detector belongs. Typically a BolometerCamera() or an optical World() object.

• units (bool) – The units in which to perform observations, can be [‘power’, ‘radiance’], defaults to ‘power’.

• accumulate (bool) – Whether this observer should accumulate samples with multiple calls to observe. Defaults to False.

• curvature_radius (float) – Detectors in real bolometer cameras may have curved corners due to machining limitations. This parameter species the corner radius.

Variables
• normal_vector (Vector3D) – The normal vector of the detector constructed from the cross product of the x and y basis vectors.

• width (float) – The extent of the bolometer foil in the basis_x direction.

• height (float) – The extent of the bolometer foil in the basis_y direction.

• pixels_as_foils (array) – A 2D array of pixels as individual BolometerFoil objects, useful for calling BolometerFoil methods on each pixel (e.g. sightline tracing). The array is indexed by (column, row).

• sightline_vectors (Vector3D) – A 2D array of vectors that point from the centre of each pixel on the foil detector to the centre of the slit. Defines the effective sightline vectors of the pixels of the detector. The array is indexed by (column, row).

>>> from raysect.core import Point3D, Vector3D, translate, rotate_basis
>>> from raysect.optical import World
>>> from cherab.tools.observers import BolometerIRVB
>>>
>>> world = World()
>>>
>>> # construct transform, relative to parent's transform
>>> centre_point = Point3D(0, 0, -0.08)
>>> basis_x = Vector3D(1, 0, 0)
>>> basis_y = Vector3D(0, 1, 0)
>>> normal = basis_x.cross(basis_y)
>>> transform = translate(*centre_point) * rotate_basis(normal, basis_y)
>>>
>>> # specify a detector, you need already created slit and camera objects
>>> width = 0.0025
>>> pixels = (10, 20)
>>> detector = BolometerIRVB("irvb", width, pixels, slit, transform, parent=camera)
as_sightlines()

Constructs a SightLine observer for each pixel in this bolometer.

Returns

A 2D array of Sightline objects.

calculate_etendue(ray_count=None, batches=None, max_distance=None)

Calculates the etendue of each pixel in this detector.

This function calculates the detector etendue by evaluating the ratio of rays that pass un-impeded through the detector’s aperture. For this method to work, the detector and its aperture structures should be the only primitives present in the scene. If any other primitives are present, the results may be misleading.

Parameters
• ray_count (int) – The number of rays used per batch (default 10000).

• batches (int) – The number of batches used to estimate the error on the etendue calculation. Default is 10.

• max_distance (float) – The maximum distance from the detector to consider intersections. If a ray makes it further than this, it is assumed to have passed through the aperture, regardless of what it hits. Use this if there are other primitives present in the scene which do not form the aperture. Default is infinity (no max distance).

Returns

a tuple (etendue, etendue_error), each of which is a 2D array of size (ncol, nrow)

calculate_sensitivity(voxel_collection, ray_count=None)

Calculates a sensitivity vector for this detector on the specified voxel collection.

This function is used for calculating sensitivity matrices which can be combined for multiple detectors into a sensitivity matrix $$\mathbf{W}$$.

Parameters
• voxel_collection (VoxelCollection) – The voxel collection on which to calculate the sensitivities.

• ray_count (int) – The number of rays to use in the calculation. This should be at least >= 10000 for decent statistics. Default is 10000.

Returns

A 3D array of sensitivities (ncol, nrow, nvoxels)

trace_sightlines()

Trace the central sightlines through each pixel in the detector to see where the sightline terminates.

Raises a RuntimeError exception if no intersections were found.

Returns

A 2D array of tuples containing the origin point, hit point and terminating surface primitive for each pixel.

10.4.2. Spectroscopic lines of sight¶

Spectroscopic line of sight allows to control main parameters of the pipeline without accessing the pipeline directly. Multiple spectroscopic line of sight can be combined into a group.

class cherab.tools.observers.spectroscopy.base._SpectroscopicObserver0DBase

A base class for spectroscopic 0D observers.

The observer allows to control some of the pipeline properties without accessing the pipelines. It has a built-in plotting method.

Multiple spectroscopic 0D observers can be combined into a group.

Variables
• origin (Point3D) – The origin point of the sight line.

• direction (Vector3D) – The observation direction of the sight line.

• display_progress (bool) – Toggles the display of live render progress.

• accumulate (bool) – Toggles whether to accumulate samples with subsequent calls to observe().

Connects pipelines of given kinds and names to this sight line. Connected pipelines are non-accumulating by default.

Parameters

properties (list) –

3-tuple list of pipeline properties in order (class, name, filter). Default is [(SpectralRadiancePipeline0D, None, None)]. The following pipeline classes are supported:

Filters are applied to the mono pipelines only, namely, PowerPipeline0D or RadiacnePipeline0D. The values provided for spectral pipelines will be ignored. The filter must be an instance of SpectralFunction or None.

get_pipeline(item=0)

Gets a pipeline by its name or index.

Parameters

item (str/int) – The name of the pipeline or its index in the list.

Return type

Pipeline0D

plot_spectrum(item=0, in_photons=False, ax=None, extras=True)

Plot the observed spectrum for a given spectral pipeline.

Parameters
• item (str/int) – The index or name of the pipeline. Default: 0.

• in_photons (bool) – If True, plots the spectrum in photon/s/nm instead of W/nm. Default is False.

• ax (Axes) – Existing matplotlib axes.

• extras (bool) – If True, set title and axis labels.

Return type

matplotlib.pyplot.axes

class cherab.tools.observers.spectroscopy.SpectroscopicSightLine(origin=None, direction=None, pipelines=None, parent=None, name=None)

A simple line of sight observer.

Multiple SpectroscopicSightLine observers can be combined into SightLineGroup.

Parameters
• origin (Point3D) – The origin point for this sight-line. (optional)

• direction (Vector3D) – The observation direction for this sight-line. (optional)

• pipelines (list) – A list of pipelines that will process the resulting spectra from this observer. Default is [SpectralRadiancePipeline0D(accumulate=False)].

>>> from matplotlib import pyplot as plt
>>> from raysect.optical import World
>>> from raysect.core.math import Point3D, Vector3D
>>> from cherab.tools.observers import SpectroscopicSightLine
>>>
>>> world = World()
...
>>> sightline = SpectroscopicSightLine(Point3D(3., 0, 0), Vector3D(-1, 0, 0), name="MySightLine", parent=world)
>>> sightline.display_progress = False  # control pipeline parameters through the group observer
>>> sightline.pixel_samples = 5000
>>> sightline.observe()
>>> sightline.plot_spectrum(in_photons=True)  # plot the spectrum
>>> plt.show()
class cherab.tools.observers.spectroscopy.SpectroscopicFibreOptic(origin=None, direction=None, pipelines=None, acceptance_angle=None, radius=None, parent=None, name=None)

An optic fibre spectroscopic observer with non-zero acceptance angle.

Rays are sampled over a circular area at the fibre tip and a conical solid angle defined by the acceptance_angle parameter.

Multiple SpectroscopicFibreOptic observers can be combined into FibreOpticGroup.

Parameters
• origin (Point3D) – The origin point for this sight-line. (optional)

• direction (Vector3D) – The observation direction for this sight-line. (optional)

• pipelines (list) – A list of pipelines that will process the resulting spectra from this observer. Default is [SpectralRadiancePipeline0D(accumulate=False)].

• acceptance_angle (float) – The angle in degrees between the z axis and the cone surface which defines the fibres solid angle sampling area.

• radius (float) – The radius of the fibre tip in metres. This radius defines a circular area at the fibre tip which will be sampled over.

>>> from matplotlib import pyplot as plt
>>> from raysect.optical import World
>>> from raysect.core.math import Point3D, Vector3D
>>> from cherab.tools.observers import SpectroscopicFibreOptic
>>>
>>> world = World()
...
>>> fibreoptic = SpectroscopicFibreOptic(Point3D(3., 0, 0), Vector3D(-1, 0, 0), name="MyFibreOptic", parent=world)
>>> fibreoptic.acceptance_angle = 5.
>>> fibreoptic.display_progress = False  # control pipeline parameters through the group observer
>>> fibreoptic.pixel_samples = 5000
>>> fibreoptic.observe()
>>> fibreoptic.plot_spectrum(in_photons=True)  # plots the spectrum
>>> plt.show()

10.4.3. Group observers¶

Group observer is a collection of observers of the same type, for example an array of line of sight. The parameters of individual observers in a group may differ. Group observer allows combined observation, namely, calling the observe function for a group leads to a sequential call of this function for each observer in the group.

class cherab.tools.observers.group.base.Observer0DGroup(parent=None, transform=None, name=None)

A base class for a group of 0D spectroscopic observers under a single scene-graph node.

A scene-graph object regrouping a series of observers as a scene-graph parent. Allows combined observation and display control simultaneously. Note that for any property except names and pipelines, the same value can be shared between all sight lines, or each sight line can be assigned with individual value.

Variables
• names (list) – A list of sight-line names.

• pipelines (list) – A list of all pipelines connected to each sight-line in the group.

• origin (list/Point3D) – The origin points for the sight lines.

• direction (list/Vector3D) – The observation directions for the sight lines.

• render_engine (list/RenderEngine) – Rendering engine used by the sight lines. Note that if the engine is shared, changing its parameters for one sight line in a group will affect all sight lines.

• display_progress (list/bool) – Toggles the display of live render progress.

• accumulate (list/bool) – Toggles whether to accumulate samples with subsequent observations.

• min_wavelength (list/float) – Lower wavelength bound for sampled spectral range.

• max_wavelength (list/float) – Upper wavelength bound for sampled spectral range.

• spectral_bins (list/int) – The number of spectral samples over the wavelength range.

• ray_extinction_prob (list/float) – Probability of ray extinction after every material intersection.

• ray_extinction_min_depth (list/float) – Minimum number of paths before russian roulette style ray extinction.

• ray_max_depth (list/int) – Maximum number of Ray paths before terminating Ray.

• ray_important_path_weight (list/float) – Relative weight of important path sampling.

• pixel_samples (list/int) – The number of samples to take per pixel.

• samples_per_task (list/int) – Minimum number of samples to request per task.

Connects pipelines of given kinds and names to each sight-line in the group. Connected pipelines are non-accumulating by default.

Parameters

properties (list) –

3-tuple list of pipeline properties in order (class, name, filter). Default is [(SpectralRadiancePipeline0D, None, None)]. The following pipeline classes are supported:

Filters are applied to the mono pipelines only, namely, PowerPipeline0D or RadiacnePipeline0D. The values provided for spectral pipelines will be ignored. The filter must be an instance of SpectralFunction or None.

observe()

Starts the observation.

plot_spectra(item=0, in_photons=False, ax=None)

Plot the spectra observed by each line of sight in the group for a given pipeline.

Parameters
• item (str/int) – The index or name of the pipeline. Default: 0.

• in_photons (bool) – If True, plots the spectrum in photon/s/nm instead of W/nm. Default is False.

• ax (Axes) – Existing matplotlib axes.

plot_total_signal(item=0, ax=None)

Plots total (wavelength-integrated) signal for each sight line in the group.

Parameters
• item (str/int) – The index or name of the pipeline. Default: 0.

• ax (Axes) – Existing matplotlib axes.

class cherab.tools.observers.group.SightLineGroup(parent=None, transform=None, name=None)

A group of spectroscopic sight-lines under a single scene-graph node.

A scene-graph object regrouping a series of ‘SpectroscopicSightLine’ observers as a scene-graph parent. Allows combined observation and display control simultaneously.

Variables

sight_lines (list) – A list of lines of sight (SpectroscopicSightLine instances) in this group.

>>> from math import cos, sin, pi
>>> from matplotlib import pyplot as plt
>>> from raysect.optical import World
>>> from raysect.core.math import Point3D, Vector3D
>>> from cherab.tools.observers import SpectroscopicSightLine, SightLineGroup
>>>
>>> world = World()
...
>>> group = SightLineGroup(parent=world)
>>> group.add_sight_line(SpectroscopicSightLine(Point3D(3., 0, 0), Vector3D(-cos(pi/10), 0, sin(pi/10)), name="SightLine 1"))
>>> group.add_sight_line(SpectroscopicSightLine(Point3D(3., 0, 0), Vector3D(-1, 0, 0), name="SightLine 2"))
>>> group.add_sight_line(SpectroscopicSightLine(Point3D(3., 0, 0), Vector3D(-cos(pi/10), 0, -sin(pi/10)), name="SightLine 3"))
(RadiancePipeline0D, 'MyMonoPipeline', None)])  # add pipelines to all sight lines in the group
>>> group.spectral_bins = 512  # same value for all sight lines in the group
>>> group.pixel_samples = [2000, 1000, 2000]  # individual value for each sight line in the group
>>> group.display_progress = False  # control pipeline parameters through the group observer
>>> group.observe()  # combined observation
>>> group.plot_spectra(item='MySpectralPipeline', in_photons=True)  # plot the spectra
>>> group.plot_total_signal(item='MyMonoPipeline')  # plot the total signals
>>> plt.show()

Adds new line of sight to the group.

Parameters

sight_line (SpectroscopicSightLine) – Sight line to add.

class cherab.tools.observers.group.FibreOpticGroup(parent=None, transform=None, name=None)

A group of fibre optics under a single scene-graph node.

A scene-graph object regrouping a series of ‘SpectroscopicFibreOptic’ observers as a scene-graph parent. Allows combined observation and display control simultaneously.

Variables
• sight_lines (list) – A list of fibre optics (SpectroscopicFibreOptic instances) in this group.

• acceptance_angle (list/float) – The angle in degrees between the z axis and the cone surface which defines the fibres solid angle sampling area. The same value can be shared between all sight lines, or each sight line can be assigned with individual value.

• radius (list/float) – The radius of the fibre tip in metres. This radius defines a circular area at the fibre tip which will be sampled over. The same value can be shared between all sight lines, or each sight line can be assigned with individual value.

>>> from math import cos, sin, pi
>>> from matplotlib import pyplot as plt
>>> from raysect.optical import World
>>> from raysect.optical.observer import SpectralPowerPipeline0D, PowerPipeline0D
>>> from raysect.core.math import Point3D, Vector3D
>>> from cherab.tools.observers import SpectroscopicFibreOptic, FibreOpticGroup
>>>
>>> world = World()
...
>>> group = FibreOpticGroup(parent=world)
>>> group.add_sight_line(SpectroscopicFibreOptic(Point3D(3., 0, 0), Vector3D(-cos(pi/10), 0, sin(pi/10)), name="Fibre 1"))
>>> group.add_sight_line(SpectroscopicFibreOptic(Point3D(3., 0, 0), Vector3D(-1, 0, 0), name="Fibre 2"))
>>> group.add_sight_line(SpectroscopicFibreOptic(Point3D(3., 0, 0), Vector3D(-cos(pi/10), 0, -sin(pi/10)), name="Fibre 3"))
>>> group.connect_pipelines([(SpectralPowerPipeline0D, 'MySpectralPipeline', None),
(PowerPipeline0D, 'MyMonoPipeline', None)])  # add pipelines to all fibres in the group
>>> group.acceptance_angle = 2  # same value for all fibres in the group
>>> group.spectral_bins = 512
>>> group.pixel_samples = [2000, 1000, 2000]  # individual value for each fibre in the group
>>> group.display_progress = False  # control pipeline parameters through the group observer
>>> group.observe()  # combined observation
>>> group.plot_spectra(item='MySpectralPipeline', in_photons=True)  # plot the spectra
>>> group.plot_total_signal(item='MyMonoPipeline')  # plot the total signals
>>> plt.show()