The SKIRT project
advanced radiative transfer for astrophysics
Classes | Public Member Functions | Private Member Functions | Private Attributes | List of all members
FluxRecorder Class Referencefinal

#include <FluxRecorder.hpp>

Classes

class  Contribution
 
class  ContributionList
 

Public Member Functions

 FluxRecorder (const SimulationItem *parentItem)
 
void calibrateAndWrite ()
 
void detect (PhotonPacket *pp, int l, double distance=std::numeric_limits< double >::infinity())
 
void finalizeConfiguration ()
 
void flush ()
 
void includeFluxDensityForDistant ()
 
void includeSurfaceBrightnessForDistant (int numPixelsX, int numPixelsY, double pixelSizeX, double pixelSizeY, double centerX, double centerY)
 
void includeSurfaceBrightnessForLocal (int numPixelsX, int numPixelsY, double solidAnglePerPixel, double incrementX, double incrementY, double centerX, double centerY, string quantityXY=string())
 
void setObserverFrameRedshift (double redshift, double angularDiameterDistance, double luminosityDistance)
 
void setRestFrameDistance (double distance)
 
void setSimulationInfo (string instrumentName, const WavelengthGrid *lambdagrid, bool hasMedium, bool hasMediumEmission)
 
void setUserFlags (bool recordComponents, int numScatteringLevels, bool recordPolarization, bool recordStatistics)
 

Private Member Functions

void recordContributions (ContributionList *contributionList)
 

Private Attributes

double _angularDiameterDistance
 
double _centerX
 
double _centerY
 
ThreadLocalMember< ContributionList_contributionLists
 
bool _hasMedium
 
bool _hasMediumEmission
 
vector< Array_ifu
 
bool _includeFluxDensity
 
bool _includeSurfaceBrightness
 
double _incrementX
 
double _incrementY
 
string _instrumentName
 
const WavelengthGrid_lambdagrid
 
bool _local
 
double _luminosityDistance
 
MediumSystem_ms
 
size_t _numPixelsInFrame
 
int _numPixelsX
 
int _numPixelsY
 
int _numScatteringLevels
 
const SimulationItem_parentItem
 
double _pixelSizeX
 
double _pixelSizeY
 
string _quantityXY
 
bool _recordComponents
 
bool _recordPolarization
 
bool _recordStatistics
 
bool _recordTotalOnly
 
double _redshift
 
vector< Array_sed
 
double _solidAnglePerPixel
 
vector< Array_wifu
 
vector< Array_wsed
 

Detailed Description

FluxRecorder is a helper class used by instruments to actually record the effects of detected photon packets. Each Instrument instance employs a single FluxRecorder instance.

Features

Depending on an instrument's needs, a FluxRecorder instance records an SED (spectral energy density) with a spatially integrated flux density for each wavelength bin, and/or a full IFU (integral field unit data cube) with a surface brightness for each pixel in an image frame for each wavelength bin. In each case, flux information can be recorded and written to file depending on user configuration.

Specifically, the class can record the individual contributions to the total flux from primary and secondary sources (i.e. emission by media), in each case splitting direct and scattered radiation. It can also store the flux as it would be seen without any attenuation, i.e. a transparent view of the system as if there were no media. Furthermore, the contributions from individual scattering levels (for primary radiation only) up to a certain maximum level can be recorded separately. When the maximum level is set to zero, this feature is disabled. Finally, the class can also record the elements of the Stokes vector for the total flux, \((I, Q, U, V)\), where the intensity \(I\) corresponds to the total flux itself. Note that the Stokes \(Q, U, V\) "flux" values can be negative.

Upon request, the class can also record information intended for calculating statistical properties of the results. Let \(N\) denote the number of primary and secondary photon packets launched during the peel-off segments of the simulation. We define \(w_i, i=1,\dots,N\) as the contribution of the \(i\)th photon packet to a particular bin (a wavelength bin for an SED, or a pixel in one of the wavelength frames for an IFU). The value of \(w_i\) includes the contributions of all photon packets peeled-off and/or scattered from the originally launched packet (called the history of that packet). Given this definition, the class tracks and outputs the sums \(\sum_i w_i^k\), with \(k=0,\dots,4\) for each bin. These sums allow calculating second order statistical properties such as the relative error \(R\) and fourth order statistical properties such as the variance of the variance VOV. For more information, see, e.g., the user manual for the MCNP code (A General Monte Carlo N-Particle Transport Code, Version 5, April 24, 2003, Revised 2/1/2008, Los Alamos National Laboratory, USA) or Camps and Baes 2018 (ApJ).

All of these output possibilities are summarized in the table below. A separate IFU output file is written for each line in the table; the first column in the table lists the portion of the output filename prefix_instr_XXX.fits indicating the IFU type. Note that an output file is created only if the corresponding information has been requested and it is meaningful. For example, if the transparent flux is know to be identical to the total flux (because there are no media), the transparent file is not written. Also, if the simulation does not include media emission, the secondary flux files are not written.

IFU file name Description Configured by
total Total attenuated flux always on
transparent Transparent flux from primary sources recordComponents = true
primarydirect Direct, unscattered flux from primary sources recordComponents = true
primaryscattered Indirect, scattered flux from primary sources recordComponents = true
primaryscatteredN Flux from primary sources that has scattered N times .. & numScatteringLevels > 0
secondarytransparent Transparent flux emitted by media recordComponents = true
secondarydirect Direct, unscattered flux emitted by media recordComponents = true
secondaryscattered Indirect, scattered flux emitted by media recordComponents = true
stokesQ Stokes vector element Q for total flux recordPolarization = true
stokesU Stokes vector element U for total flux recordPolarization = true
stokesV Stokes vector element V for total flux recordPolarization = true
statsN Sum of individual photon contributions to the power of N recordStatistics = true

The SED information is written in a maximum of two text column files. The first file, called prefix_instr_sed.txt, includes a column for each of the requested flux components in the order indicated by the table below. The columns for each block are either all present or all absent as requested in the configuration, even if the numbers are zero or identical to other columns. This allows the column indices to be determined solely based on knowledge of the instrument configuration flags, without taking into account whether the simulation actually includes the corresponding feature (e.g., media emission or polarization).

Block Configured by
Total flux always on
Transparent fluxes and flux components recordComponents = true
Stokes vector elements recordPolarization = true
N-times scattered primary flux recordComponents = true & numScatteringLevels > 0

The second file, called prefix_instr_sedstats.txt, is written only if statistics are requested. It includes a column for the wavelength plus a column for each of the individual photon contribution sums, for powers from zero to 4.

Calling sequence

A FluxRecorder instance expects a rigourous calling sequence. During setup, the instrument configures the FluxRecorder's operation, specifying the wavelength grid, the items to be recorded (SED, IFU, individual flux components, statistics), flux calibration settings (instrument type, distance, redshift), and some additional information on the simulation in which the instrument is embedded (e.g., is there any secondary emission). The configuration must be completed by calling the finalizeConfiguration() function.

To record the effects of detecting a photon packet, the instrument invokes the detect() function. This function is thread-safe, so it may be (and often is) called from multiple parallel execution threads. After the parallel threads have completed the work on a series of photon packets, and before the parallel threads are actually destructed, the instrument should call the flush() function from a single thread to process any information buffered by the detect() function in thread-local storage. Finally, at the end of the simulation, the instrument calls the calibrateAndWrite() function to output the recorded information.

Flux calibration

A FluxRecorder instance handles the conversion of the detected photon packet contributions to a corresponding observed quantity for each spectral and/or spatial bin. This process is called flux calibration and it depends to some extent on whether the instrument associated with the flux recorder is "distant" or "local".

A distant instrument is placed at a large distance from the model under study. The observed portion of the sky is approximated by a plane perpendicular to the line of sight rather than a part of a sphere. The instrument uses parallel projection and considers all photon packets to originate at the same distance from the instrument. Consequently, the incoming photon packet contributions can simply be accumulated for each bin and flux calibration can occur on the aggregated result. Assuming a non-relativistic distance, the calibration for the flux densities \(F_\lambda\) in an SED is

\[ F_\lambda = \frac{1}{\Delta\lambda} \, \frac{1}{4\pi d_\mathrm{m}^2} \, L_\mathrm{bin}\]

where \(L_\mathrm{bin}\) is the aggregated photon packet luminosity contribution in a spectral bin, \(\Delta\lambda\) is the width of that bin, and \(d_\mathrm{m}\) is the distance from the model to the instrument. The calibration for the surface brightness values \(f_\lambda\) in an IFU is

\[ f_\lambda = \frac{1}{\Delta\lambda} \, \frac{1}{4\pi d_\mathrm{m}^2} \, \frac{1}{\Omega_\mathrm{distant}}\, L_\mathrm{bin}\]

where \(\Omega_\mathrm{distant}\) is the solid angle subtended by the detector pixel corresponding to the bin. For a distant instrument using parallel projection, the latter is given by

\[\Omega_\mathrm{distant} = 4\arctan\left(\frac{s_\mathrm{x}}{2d_\mathrm{m}}\right) \arctan\left(\frac{s_\mathrm{y}}{2d_\mathrm{m}}\right) \]

where \(s_\mathrm{x}\) and \(s_\mathrm{y}\) represent the field of view (in model units) of a pixel in each direction. For relativistic distances these relations become slightly more involved, as discussed in a seperate concept note on cosmological redshift.

A local instrument is placed near or even inside the model. The mapping between incoming photon packet trajectories and detector pixels is determined by the instrument. Although all distances are considered to be non-relativistic, photon packets can now originate at various distances from the instrument, with a wide dynamic range. The FluxRecorder class does not support recording SEDs for local instruments. The calibration for the surface brightness values \(f_\lambda\) in an IFU now becomes

\[ f_\lambda = \frac{1}{\Delta\lambda} \, \frac{1}{4\pi d_\mathrm{pp}^2} \, \frac{1}{\Omega_\mathrm{local}}\, L_\mathrm{pp}\]

where \(L_\mathrm{pp}\) is the luminosity contribution by a particular photon packet, \(d_\mathrm{pp}\) is the distance of the packet's originating position to the instrument, and \(\Omega_\mathrm{local}\) is the solid angle subtended by the detector pixel corresponding to the bin. The correction for distance now must be performed for each photon packet individually. Furthermore, the solid angle subtended by a detector pixel now depends on the projection applied by the instrument. The current implementation assumes that the solid angle is identical for all pixels in the detector, alhough this is not generally true for all instrument projections. In that case, the instrument should specify a representative value and advise the user to avoid situations where the actual solid angles deviate much from this value.

Memory usage

A FluxRecorder instance dynamically adjusts its memory allocation to the configuration and simulation characteristics. Detector arrays for individual flux components, polarization, or statistics are allocated only when requested in the configuration. Also, for example, if there is no secondary emission in the simulation, the corresponding detector arrays are not allocated, even if recording of individual components is requested in the configuration.

Constructor & Destructor Documentation

◆ FluxRecorder()

FluxRecorder::FluxRecorder ( const SimulationItem parentItem)

The constructor initializes the FluxRecorder to a configuration that records nothing. The argument specifies a simulation item in the hierarchy of the caller (usually the caller itself). It is used to get a human-readable name for the caller and to retrieve a logger and a unit system from the simulation hierarchy.

Member Function Documentation

◆ calibrateAndWrite()

void FluxRecorder::calibrateAndWrite ( )

This function calibrates and outputs the instrument data. The calibration includes dividing the luminosities (W) recorded for each bin by the wavelength bin width to obtain specific luminosities (W/m) and further conversion to flux density (incorporating distance) and/or to surface brightness (incorporating distance and solid angle per pixel) based on the information passed during configuration. The function also converts the resulting values from internal units to output units depending on the simulation's choices for flux output style.

For more information on flux calibration and on the names and contents of the generated files, see the documentation in the header of this class.

◆ detect()

void FluxRecorder::detect ( PhotonPacket pp,
int  l,
double  distance = std::numeric_limits< double >::infinity() 
)

This function simulates the detection of a photon packet by the recorder as determined by its configuration. This function is thread-safe, so it may be (and often is) called from multiple parallel execution threads.

The calling instrument is responsible for providing the index l of the pixel in the instrument frame where the photon packet arrives, because this depends on the projection being used. In addition, the instrument can specify a distance from the photon packet's last interaction site to the instrument. For distant instruments with parallel projection, this distance should be left at its default value of infinity. For instruments that may be placed close by or inside the model, the actual distance should be specified so that the flux can be properly calibrated for each individual photon packet.

All other information is obtained directly or indirectly from the photon packet. If there is an obscuring medium, the optical depth from the photon packet's last interaction site to the instrument is determined and the corresponding extincton is applied to the packet's contribution before detection.

◆ finalizeConfiguration()

void FluxRecorder::finalizeConfiguration ( )

This function completes the configuration of the recorder. It must be called after any of the configuration functions, and before the first invocation of the detect() function.

◆ flush()

void FluxRecorder::flush ( )

This function processes and clears any information that may have been buffered by the detect() function in thread-local storage. It is not thread-safe. After parallel threads have completed the work on a series of photon packets, and before the parallel threads are actually destructed, the flush() function should be called from a single thread.

◆ includeFluxDensityForDistant()

void FluxRecorder::includeFluxDensityForDistant ( )

This function enables recording of spatially integrated flux densities, i.e. an SED, for a distant instrument. Recording of spatially integrated flux densities for local instruments is not supported, so this function should not be called for a local instrument.

◆ includeSurfaceBrightnessForDistant()

void FluxRecorder::includeSurfaceBrightnessForDistant ( int  numPixelsX,
int  numPixelsY,
double  pixelSizeX,
double  pixelSizeY,
double  centerX,
double  centerY 
)

This function enables recording of IFU data cubes, i.e. a surface brightness image frame for each wavelength, for a distant instrument. The number of pixels and the pixel sizes are used to calibrate the surface brightness; the center coordinates are used only for the metadata in the output file. The coordinates and pixel sizes are converted to angular sizes before being written to the metadata of the output file. This function should not be called for a local instrument.

◆ includeSurfaceBrightnessForLocal()

void FluxRecorder::includeSurfaceBrightnessForLocal ( int  numPixelsX,
int  numPixelsY,
double  solidAnglePerPixel,
double  incrementX,
double  incrementY,
double  centerX,
double  centerY,
string  quantityXY = string() 
)

This function enables recording of IFU data cubes, i.e. a surface brightness image frame for each wavelength, for a local instrument. The solid ange per pixel is used to calibrate the surface brightness. The remaining arguments are used only for the metadata in the output file. If the quantity string is nonempty, it should specify a valid SKIRT quantity name and the increment and center values are converted to the corresponding output units. This function should not be called for a distant instrument.

◆ recordContributions()

void FluxRecorder::recordContributions ( ContributionList contributionList)
private

This private helper function records the photon packet history contributions in the specified list into the statistics arrays.

◆ setObserverFrameRedshift()

void FluxRecorder::setObserverFrameRedshift ( double  redshift,
double  angularDiameterDistance,
double  luminosityDistance 
)

This function configures the redshift and relativistic distances of the recorder's observer frame for a distant instrument. The specified redshift and distances must be nonzero. The client must call either the setRestFrameDistance() or setObserverFrameRedshift() functions, not both. This function should not be called for a local instrument.

◆ setRestFrameDistance()

void FluxRecorder::setRestFrameDistance ( double  distance)

This function configures the distance of the recorder in the model's rest frame for a distant instrument. The specified distance must be nonzero. The client must call either the setRestFrameDistance() or setObserverFrameRedshift() functions, not both. This function should not be called for a local instrument.

◆ setSimulationInfo()

void FluxRecorder::setSimulationInfo ( string  instrumentName,
const WavelengthGrid lambdagrid,
bool  hasMedium,
bool  hasMediumEmission 
)

This function configures information on the simulation in which the recorder is embedded. In order of appearance, the arguments specify the name of the associated instrument, the wavelength grid of the instrument, whether the simulation includes at least some media, and whether the simulation includes emission from those media.

◆ setUserFlags()

void FluxRecorder::setUserFlags ( bool  recordComponents,
int  numScatteringLevels,
bool  recordPolarization,
bool  recordStatistics 
)

This function configures the user requirements for recording, respectively, flux components, individual scattering level contributions, polarization, and information for calculating statistics. See the documentation in the header of this class for more information.


The documentation for this class was generated from the following file: