Simulation (esc_etc.simulation)

Top-level ESC ETC orchestrator: composes Telescope, Sensor, Scene, Coronagraph.

count_rate_components extracts Observatory.make_observation: it normalizes the host on the FPM-free Sensor.bandpass, derives planet/speckle by scaling, computes zodi/exozodi with the resel factor, then multiplies EVERY rate by the flat FPM throughput k = coronagraph.off_axis_throughput (plan physics-fact #1).

Every SNR term is evaluated in ONE photometric aperture, chosen by Sensor.aperture (the resel, Omega = pi (lambda/2D)^2, by default; issue #10) with encircled energy EE = Sensor.ee_fraction for point sources:

R_planet  = R_planet,ref * k * EE           planet spectrum normalised dmag
                                            fainter than the host; k = FPM
                                            off-axis throughput
R_speckle = R_host * C * k * EE             C = raw contrast, see Coronagraph
R_zodi    = SB_zodi * Omega * k             (exozodi likewise)
N_pix     = Omega / plate_scale^2           (dark current, read noise)

k on the diffuse terms stands in for the diffuse-background transmission. ponytail: assumed equal to the point-source core throughput; split it out when the FPM data records total transmission separately.

class esc_etc.simulation.Simulation(telescope, sensor, scene, coronagraph, noise_model=None)[source]

Bases: _MetaHolder_

A telescope, sensor, scene and coronagraph, turned into SNR and time.

Build one with from_default() or from_components(). Change parameters with update(child__param=...) and put everything back with reset(). Times passed to the methods may be astropy quantities or plain numbers in seconds. Every standard plot is a plot_* method.

classmethod from_components(telescope, sensor, scene, coronagraph, noise_model=None)[source]
classmethod from_default(hoststarmag=-0.353, planetdeltamag=20.0, contrast=1e-08, ppgain=10, separation=0.2, bg_flux=22.5, exobg_flux=21.0, arm='arm_a', mag_system='vega', hoststar_band=None, filter='F630N', lifetime='eol')[source]

See get_scene for what band each magnitude is quoted in.

filter (a key of esc_etc.FILTERS such as "R1" / "F620N", default esc_etc.DEFAULT_FILTER) uses that ESC filter’s measured curve as the full sensor bandpass and its design wavelength as the telescope’s central wavelength. lifetime picks the "eol" (end of life, default) or "bol" curve set. filter=None is the legacy option: the generic box-filter chain assembled from the configuration files, which has no BOL/EOL variants.

count_rate_components()[source]
get_snr(total_time, frame_time)[source]

SNR after total_time on target in frames of frame_time.

Both times accept astropy quantities or plain numbers (seconds). Returns a dict with snr, signal_e, noise_e, reference_noise_e, science_time, charged_time and the speckle floor rate M. Warns when a frame would saturate.

get_int_time_for_snr(snr, frame_time)[source]

Integration time to reach snr with frames of frame_time (quantity or seconds).

Returns int_time (whole frames), int_time_continuous (exact) and the noise_terms rates. NaN when snr is above the speckle plateau.

saturation_time()[source]

Frame time at which the brightest dark-hole pixel reaches sensor.headroom * sensor.well_depth.

Planet and speckle put sensor.peak_pixel_fraction of their in-aperture rate on the peak pixel; zodi and exozodi spread uniformly over num_psf_pixels; dark current adds per pixel. The occulted host is out of scope: this is the dark-hole science ROI, not the stellar core behind the FPM.

is_saturated(frame_time)[source]

True when a frame of frame_time (quantity or seconds) exceeds saturation_time().

plot(**kw)[source]

2 x 3 overview; see esc_etc.plotting.plot_overview().

plot_count_rates(**kw)[source]

See esc_etc.plotting.plot_count_rates().

plot_snr_vs_time(**kw)[source]

See esc_etc.plotting.plot_snr_vs_time() (supports sweep=).

plot_bandpass(**kw)[source]

See esc_etc.plotting.plot_bandpass().

plot_spectra(**kw)[source]

See esc_etc.plotting.plot_spectra().

plot_offaxis_throughput(**kw)[source]

See esc_etc.plotting.plot_offaxis_throughput().

plot_aperture(**kw)[source]

See esc_etc.plotting.plot_aperture().