Photon Shooting¶
Photon Arrays¶
- jax_galsim.photon_array.fixed_photon_array_size(size)[source]¶
Context manager to temporarily set a fixed size for photon arrays.
- class jax_galsim.PhotonArray(N, x=None, y=None, flux=None, dxdz=None, dydz=None, wavelength=None, pupil_u=None, pupil_v=None, time=None, _nokeep=None)[source]¶
Bases:
objectThe PhotonArray class encapsulates the concept of a collection of photons incident on a detector.
LAX-backend implementation of
galsim.photon_array.PhotonArray().🔪 JAX-GalSim - The Sharp Bits 🔪
JAX-GalSim PhotonArrays have significant differences from the original GalSim.
They always copy input data and operations on them always copy.
They (usually) do not do any type/size checking on input data.
They do not support indexed assignement directly on the attributes.
The additional properties
dxdz,dydz,wavelength,pupil_u,pupil_v, andtimeare set to arrays of NaNs by default. They are thus always allocated. However, the methods like hasAllocatedAngles etc. return false if the arrays are all NaNs.
Further, a context manager
fixed_photon_array_sizeis provided to temporarily set a fixed size for photon arrays.This functionality is useful when applying JIT to operations that vary the number of photons drawn using Poisson statistics.
When using this context manager, the attribute
_nokeepstores a boolean mask indicating which photons are to be kept.The attribute
_num_keepstores the number of photons to be kept. If you set this attribute, the_nokeepmask is updated by sorting_nokeepso that things to be kept are at the start, the first_num_keepphotons are marked to be kept, and finally the array is sorted back to its original order.You may get an error if you ask for more photons than the fixed size, but not always, especially in JITed code.
Operations on photon arrays with fixed sizes but different _num_keep values are not defined and will not raise an error.
The
.fluxproperty scales._fluxby the ratio of the fixed size to the number of kept photons and sets non-kept photons to zero flux. Setting.fluxto._fluxwill break things badly.Profiles should always draw the full number of photons given by
.size()orlen()so that they use fixed array sizes and things are JIT compatible.
The ``_nokeep``, ``_num_keep``, and associated methods are private and should not be set by hand unless you know what you are doing!
- Parameters:
N – The number of photons to store in this PhotonArray. This value cannot be changed.
x – Optionally, the initial x values. [default: None]
y – Optionally, the initial y values. [default: None]
flux – Optionally, the initial flux values. [default: None]
dxdz – Optionally, the initial dxdz values. [default: None]
dydz – Optionally, the initial dydz values. [default: None]
wavelength – Optionally, the initial wavelength values (in nm). [default: None]
pupil_u – Optionally, the initial pupil_u values. [default: None]
pupil_v – Optionally, the initial pupil_v values. [default: None]
time – Optionally, the initial time values. [default: None]
Original GalSim Documentation
A PhotonArray object is not typically constructed directly by the user. Rather, it is typically constructed as the return value of the GSObject.shoot method. At this point, the photons only have x,y,flux values.
Then there are a number of Photon Operators, which perform various modifications to the photons such as giving them wavelengths (WavelengthSampler or inclination angles (FRatioAngles) or move them around according to the effect of differential chromatic refraction (DCR; PhotonDCR).
One could also add functionality to remove some photons due to fringing or vignetting, but these are not yet implemented.
A PhotonArray instance has the following attributes, each of which is a numpy array:
- Attributes:
- x: The incidence x position of the photons in image coordinates (pixels),
typically measured at the top of the detector.
- y: The incidence y position of the photons in image coordinates (pixels),
typically measured at the top of the detector.
- flux: The flux of the photons in units of photons. Typically, these are all 1,
but see the note below for reasons some photons might have flux != 1.
- dxdz: The tangent of the inclination angles in the x direction. Note that we define
the +z direction as towards towards the dielectric medium of the detector and -z as towards vacuum; consequently, a photon with increasing x in time has positive dxdz.
- dydz: The tangent of the inclination angles in the y direction. Note that we define
the +z direction as towards towards the dielectric medium of the detector and -z as towards vacuum; consequently, a photon with increasing y in time has positive dydz.
wavelength The wavelength of the photons (in nm) pupil_u: Horizontal location of photon as it intersected the entrance pupil plane
(meters).
- pupil_v: Vertical location of photon as it intersected the entrance pupil plane
(meters).
time: Time stamp for photon impacting the pupil plane (seconds).
Unlike most GalSim objects (but like Image), PhotonArrays are mutable. It is permissible to write values to the above attributes with code like:
>>> photon_array.x += numpy.random.random(1000) * 0.01 >>> photon_array.flux *= 20. >>> photon_array.wavelength = sed.sampleWavelength(photonarray.size(), bandpass) etc.
All of these will update the existing numpy arrays being used by the photon_array instance.
Note
Normal photons have flux=1, but we allow for “fat” photons that combine the effect of several photons at once for efficiency. Also, some profiles need to use negative flux photons to properly implement photon shooting (e.g. InterpolatedImage, which uses negative flux photons to get the interpolation correct). Finally, when we “remove” photons, for better efficiency, we actually just set the flux to 0 rather than recreate new numpy arrays.
The initialization constructs a PhotonArray to hold N photons, but does not set the values of anything yet. The constructor allocates space for the x,y,flux arrays, since those are always needed. The other arrays are only allocated on demand if the user accesses these attributes.
- classmethod fromArrays(x, y, flux, dxdz=None, dydz=None, wavelength=None, pupil_u=None, pupil_v=None, time=None, is_corr=False)[source]¶
Create a PhotonArray from pre-allocated numpy arrays without any copying.
LAX-backend implementation of
galsim.photon_array.fromArrays().🔪 JAX-GalSim - The Sharp Bits 🔪
JAX-GalSim does not do input type/size checking.
- Parameters:
x – X values.
y – X values.
flux – Flux values.
dxdz – Optionally, the initial dxdz values. [default: None]
dydz – Optionally, the initial dydz values. [default: None]
wavelength – Optionally, the initial wavelength values (in nm). [default: None]
pupil_u – Optionally, the initial pupil_u values (in m). [default: None]
pupil_v – Optionally, the initial pupil_v values (in m). [default: None]
time – Optionally, the initial time values (in s). [default: None]
is_corr – Whether or not the photons are correlated. [default: False]
Original GalSim Documentation
The normal PhotonArray constructor always allocates new arrays and copies any provided initial values into those new arrays. This class method, by constrast, constructs a PhotonArray that references existing numpy arrays, so that any PhotonOps or photon shooting of GSObjects applied to the resulting PhotonArray will also be reflected in the original arrays.
Note that the input arrays must all be the same length, have dtype float64 and be c_contiguous.
- classmethod tree_unflatten(aux_data, children)[source]¶
Recreates an instance of the class from flatten representation
- size()[source]¶
Return the size of the photon array. Equivalent to
len(self).LAX-backend implementation of
galsim.photon_array.size().
- property x¶
The incidence x position in image coordinates (pixels), typically at the top of the detector.
LAX-backend implementation of
x().🔪 JAX-GalSim - The Sharp Bits 🔪
JAX-GalSim PhotonArray properties do not support assignment at indices.
- property y¶
The incidence y position in image coordinates (pixels), typically at the top of the detector.
LAX-backend implementation of
y().🔪 JAX-GalSim - The Sharp Bits 🔪
JAX-GalSim PhotonArray properties do not support assignment at indices.
- property flux¶
The flux of the photons.
LAX-backend implementation of
flux().🔪 JAX-GalSim - The Sharp Bits 🔪
JAX-GalSim PhotonArray properties do not support assignment at indices.
- property dxdz¶
dx/dz.
LAX-backend implementation of
dxdz().🔪 JAX-GalSim - The Sharp Bits 🔪
JAX-GalSim PhotonArray properties do not support assignment at indices.
- Type:
The tangent of the inclination angles in the x direction
- property dydz¶
dy/dz.
LAX-backend implementation of
dydz().🔪 JAX-GalSim - The Sharp Bits 🔪
JAX-GalSim PhotonArray properties do not support assignment at indices.
- Type:
The tangent of the inclination angles in the y direction
- property wavelength¶
The wavelength of the photons (in nm).
LAX-backend implementation of
wavelength().🔪 JAX-GalSim - The Sharp Bits 🔪
JAX-GalSim PhotonArray properties do not support assignment at indices.
- property pupil_u¶
Horizontal location of photon as it intersected the entrance pupil plane.
LAX-backend implementation of
pupil_u().🔪 JAX-GalSim - The Sharp Bits 🔪
JAX-GalSim PhotonArray properties do not support assignment at indices.
- property pupil_v¶
Vertical location of photon as it intersected the entrance pupil plane.
LAX-backend implementation of
pupil_v().🔪 JAX-GalSim - The Sharp Bits 🔪
JAX-GalSim PhotonArray properties do not support assignment at indices.
- property time¶
Time stamp of when photon encounters the pupil plane.
LAX-backend implementation of
time().🔪 JAX-GalSim - The Sharp Bits 🔪
JAX-GalSim PhotonArray properties do not support assignment at indices.
- hasAllocatedAngles()[source]¶
Returns whether the arrays for the incidence angles dxdz and dydz have been allocated.
LAX-backend implementation of
galsim.photon_array.hasAllocatedAngles().
- allocateAngles()[source]¶
Allocate memory for the incidence angles, dxdz and dydz.
LAX-backend implementation of
galsim.photon_array.allocateAngles().🔪 JAX-GalSim - The Sharp Bits 🔪
This is a no-op for JAX-Galsim.
- hasAllocatedWavelengths()[source]¶
Returns whether the wavelength array has been allocated.
LAX-backend implementation of
galsim.photon_array.hasAllocatedWavelengths().
- allocateWavelengths()[source]¶
Allocate the memory for the wavelength array.
LAX-backend implementation of
galsim.photon_array.allocateWavelengths().🔪 JAX-GalSim - The Sharp Bits 🔪
This is a no-op for JAX-Galsim.
- hasAllocatedPupil()[source]¶
Returns whether the arrays for the pupil coordinates pupil_u and pupil_v have been allocated.
LAX-backend implementation of
galsim.photon_array.hasAllocatedPupil().
- allocatePupil()[source]¶
Allocate the memory for the pupil coordinates, pupil_u and pupil_v.
LAX-backend implementation of
galsim.photon_array.allocatePupil().🔪 JAX-GalSim - The Sharp Bits 🔪
This is a no-op for JAX-Galsim.
- hasAllocatedTimes()[source]¶
Returns whether the array for the time stamps time has been allocated.
LAX-backend implementation of
galsim.photon_array.hasAllocatedTimes().
- allocateTimes()[source]¶
Allocate the memory for the time stamps, time.
LAX-backend implementation of
galsim.photon_array.allocateTimes().🔪 JAX-GalSim - The Sharp Bits 🔪
This is a no-op for JAX-Galsim.
Returns whether the photons are correlated
LAX-backend implementation of
galsim.photon_array.isCorrelated().
Set whether the photons are correlated
LAX-backend implementation of
galsim.photon_array.setCorrelated().
- getTotalFlux()[source]¶
Return the total flux of all the photons.
LAX-backend implementation of
galsim.photon_array.getTotalFlux().
- setTotalFlux(flux)[source]¶
Rescale the photon fluxes to achieve the given total flux.
LAX-backend implementation of
galsim.photon_array.setTotalFlux().Original GalSim Documentation
- Parameter:
flux: The target flux
- scaleFlux(scale)[source]¶
Rescale the photon fluxes by the given factor.
LAX-backend implementation of
galsim.photon_array.scaleFlux().Original GalSim Documentation
- Parameter:
scale: The factor by which to scale the fluxes.
- scaleXY(scale)[source]¶
Scale the photon positions (x and y) by the given factor.
LAX-backend implementation of
galsim.photon_array.scaleXY().Original GalSim Documentation
- Parameter:
scale: The factor by which to scale the positions.
- assignAt(istart, rhs)[source]¶
Assign the contents of another PhotonArray to this one starting at istart.
LAX-backend implementation of
galsim.photon_array.assignAt().- Parameters:
istart – The first index at which to insert new values.
rhs – The other PhotonArray from which to get the values.
- copyFrom(rhs, target_indices=slice(None, None, None), source_indices=slice(None, None, None), do_xy=True, do_flux=True, do_other=True)[source]¶
Copy some contents of another PhotonArray to some elements of this one.
LAX-backend implementation of
galsim.photon_array.copyFrom().🔪 JAX-GalSim - The Sharp Bits 🔪
The JAX version of PhotonArray.copyFrom does not raise for out of bounds indices.
- Parameters:
rhs – The PhotonArray from which to get values.
target_indices – The indices at which to assign values in the current PhotonArray (self). [default: slice(None)]
source_indices – The indices from which to get values from the PhotonArray,
rhs. [default: slice(None)]do_xy – Whether to include copying the x and y arrays. [default: True]
do_flux – Whether to include copying the flux array. [default: True]
do_other – Whether to include copying the other arrays (angles, wavelength, pupil positions, time). [default: True]
Original GalSim Documentation
Specifically each element of rhs[source_indices] is mapped to self[target_indices]. The values s1 and s2 may be slices, list of indices, or anything else that is a valid key for a numpy array.
- convolve(rhs, rng=None)[source]¶
Convolve this PhotonArray with another.
LAX-backend implementation of
galsim.photon_array.convolve().Original GalSim Documentation
..note:
If both self and rhs have wavelengths, angles, pupil coordinates or times assigned, then the values from the first array (i.e. self) take precedence.
- addTo(image)[source]¶
Add flux of photons to an image by binning into pixels.
LAX-backend implementation of
galsim.photon_array.addTo().🔪 JAX-GalSim - The Sharp Bits 🔪
The JAX equivalent of galsim.PhotonArray.addTo may not raise for undefined bounds.
- Parameters:
image – The Image to which the photons’ flux will be added.
Original GalSim Documentation
Photons in this PhotonArray are binned into the pixels of the input Image and their flux summed into the pixels. The Image is assumed to represent surface brightness, so photons’ fluxes are divided by image pixel area. Photons past the edges of the image are discarded.
- Returns:
the total flux of photons the landed inside the image bounds.
- classmethod makeFromImage(image, max_flux=1.0, rng=None)[source]¶
Turn an existing Image into a PhotonArray that would accumulate into this image.
LAX-backend implementation of
galsim.photon_array.makeFromImage().- Parameters:
image – The image to turn into a PhotonArray
max_flux – The maximum flux value to use for any output photon [default: 1]
rng – A BaseDeviate to use for the random number generation [default: None]
Original GalSim Documentation
The flux in each non-zero pixel will be turned into 1 or more photons with random positions within the pixel bounds. The
max_fluxparameter (which defaults to 1) sets an upper limit for the absolute value of the flux of any photon. Pixels with abs values > maxFlux will spawn multiple photons.- Returns:
a PhotonArray
- write(file_name)[source]¶
Write a PhotonArray to a FITS file.
LAX-backend implementation of
galsim.photon_array.write().- Parameters:
file_name – The file name of the output FITS file.
Original GalSim Documentation
The output file will be a FITS binary table with a row for each photon in the PhotonArray. Columns will include ‘id’ (sequential from 1 to nphotons), ‘x’, ‘y’, and ‘flux’. Additionally, the columns ‘dxdz’, ‘dydz’, and ‘wavelength’ will be included if they are set for this PhotonArray object.
The file can be read back in with the classmethod PhotonArray.read:
>>> photons.write('photons.fits') >>> photons2 = galsim.PhotonArray.read('photons.fits')
- classmethod read(file_name)[source]¶
Create a PhotonArray, reading the photon data from a FITS file.
LAX-backend implementation of
galsim.photon_array.read().- Parameters:
file_name – The file name of the input FITS file.
Original GalSim Documentation
The file being read in is not arbitrary. It is expected to be a file that was written out with the PhotonArray.write method.:
>>> photons.write('photons.fits') >>> photons2 = galsim.PhotonArray.read('photons.fits')
Sensors¶
- class jax_galsim.Sensor[source]¶
Bases:
objectThe base class for other sensor models, and also an implementation of the simplest possible sensor model that just converts each photon into an electron and drops it in the appropriate pixel.
LAX-backend implementation of
galsim.sensor.Sensor().- accumulate(photons, image, orig_center=None, resume=False)[source]¶
Accumulate the photons incident at the surface of the sensor into the appropriate pixels in the image.
LAX-backend implementation of
galsim.sensor.accumulate().- Parameters:
photons – A PhotonArray instance describing the incident photons.
image – The Image into which the photons should be accumuated.
orig_center – The Position of the (0,0) point in the original image coordinates. [default: (0,0)]
resume – Resume accumulating on the same image as a previous call to accumulate. In the base class, this has no effect, but it can provide an efficiency gain for some derived classes. [default: False]
Original GalSim Documentation
Each photon has a position, which corresponds to the (x,y) position at the top of the sensor. In general, they may also have incidence directions and wavelengths, although these are not used by the base class implementation.
The base class implementation simply accumulates the photons above each pixel into that pixel.
- Returns:
the total flux that fell onto the image.
- calculate_pixel_areas(image, orig_center=galsim.PositionI(x=0, y=0), use_flux=True)[source]¶
Return the pixel areas according to the given sensor.
LAX-backend implementation of
galsim.sensor.calculate_pixel_areas().- Parameters:
image – The Image with the current flux values.
orig_center – The Position of the (0,0) point in the original image coordinates. [default: (0,0)]
use_flux – Whether to properly handle the current flux in the image (True) or to just calculate the pixel areas for a zero-flux image (False). [default: True]
Original GalSim Documentation
If the pixels are all the same size, then this should just return 1.0.
But if the pixels vary in size, it should return an Image with the pixel areas relative to the nominal pixel size. The input image gives the flux values if relevant (e.g. to set the current levels of the brighter-fatter distortions).
The returned image will have the same size and bounds as the input image, and will have for its flux values the net pixel area for each pixel according to the sensor model.
- Returns:
either 1.0 or an Image with the pixel areas (The base class return 1.0.)