diff --git a/docs/romanisim/bandpass.rst b/docs/romanisim/bandpass.rst index db7d2e5c..db0ca52a 100644 --- a/docs/romanisim/bandpass.rst +++ b/docs/romanisim/bandpass.rst @@ -3,7 +3,7 @@ Bandpasses The simulator can render scenes in a number of different bandpasses. The choice of bandpass affects the point spread function used, the sky backgrounds, the fluxes of sources, and the reference files requested. -At present, romanisim simply passes the choice of bandpass to other packages---to webbpsf for PSF modeling, to galsim.roman for sky background estimation, to CRDS for reference file selection, or to the catalog for the selection of appropriate fluxes. However, because catalog fluxes are specified in "maggies" (i.e., in linear fluxes on the AB scale), the simulator needs to know how to convert between a maggie and the number of photons Roman receives from a source. Accordingly, the simulator knows about the AB zero points of the Roman filters, as derived from https://roman.gsfc.nasa.gov/science/WFI_technical.html . +At present, romanisim simply passes the choice of bandpass to other packages---to webbpsf for PSF modeling, to galsim.roman for sky background estimation, to CRDS for reference file selection, or to the catalog for the selection of appropriate fluxes. However, because catalog fluxes are specified in "maggies" (i.e., in linear fluxes on the AB scale), the simulator needs to know how to convert between a maggie and the number of photons Roman receives from a source. Accordingly, the simulator knows about the AB zero points of the Roman filters, as derived from https://roman.gsfc.nasa.gov/science/WFI_technical.html . The conversion between photons received and fluxes in AB "maggies" is determined by integrating a flat 3631 Jy AB reference spectrum over the Roman filters to determine the number of photons per second corresponding to a zeroth magnitude AB source. One technical note: it is unclear what aperture is used for the bandpasses provided by Goddard. The Roman PSF formally extends to infinity and some light is received by the detector but is so far from the center of the PSF that it is not useful for flux, position, or shape measurements. Often for the purposes of computing effective area curves only light landing within a fixed aperture is counted. Presently the simulator assumes that an infinite aperture is used. This can result in an approximately 10% different flux scale than more reasonable aperture selections. diff --git a/docs/romanisim/l1.rst b/docs/romanisim/l1.rst index e1254ccc..a9c0a85c 100644 --- a/docs/romanisim/l1.rst +++ b/docs/romanisim/l1.rst @@ -39,9 +39,13 @@ This persistence rate is sampled with a Poisson distribution and added to each p Persistence-affected pixels are expected to be rare, and are tracked sparsely via a list of the indices of affected pixels, the amount of the illumination, and the times of their illumination. Pixels are dropped from persistence tracking when their persistence rate is less than one electron per 100 seconds. If the same pixel is receives large fluxes multiple times, these are treated as two independent events and the resulting persistence flux is handled by summing the persistence rates given above over each event. -Cosmic rays +Cosmic rays ----------- -Cosmic rays are added to the simulation read-by-read. The cosmic ray parameters follow Wu et al. (2023). The locations of cosmic rays are chosen at random to sample the focal plane uniformly. Lengths are chosen according to a power law distribution :math:`p(l) \\sim l^{-4.33}`, with lengths between 10 and 10,000 microns. Charge deposition rates per micron are selected from a Moyal distribution located at 120 electrons per micron with a width of 50 electrons per micron. An idealized charge is computed for each pixel in a read according to the product of the deposition rate per micron and the length of the cosmic ray's path within that pixel. This idealized charge is Poisson sampled and added to the relevant pixels in a read. +Cosmic rays are added to the simulation read-by-read. The cosmic ray parameters follow Wu et al. (2023). The locations of cosmic rays are chosen at random to sample the focal plane uniformly. Lengths are chosen according to a power law distribution :math:`p(l) \\sim l^{-4.33}`, with lengths between 10 and 10,000 microns. Charge deposition rates per micron are selected from a Moyal distribution located at 120 electrons per micron with a width of 50 electrons per micron. An idealized charge is computed for each pixel in a read according to the product of the deposition rate per micron and the length of the cosmic ray's path within that pixel. This idealized charge is Poisson sampled and added to the relevant pixels in a read. + +Gain +---- +L1 files are in units of DN. We convert from photons to DN using gains from CRDS or a default values of 2 electron per DN, treating electrons and photons as equivalent. This neglects the possibility that the quantum yield may be different from 1 at certain wavelengths, in particular in the blue, where `Givans+2022 `_ find a quantum field of up to 1.05. .. automodapi:: romanisim.l1 .. automodapi:: romanisim.nonlinearity diff --git a/docs/romanisim/parameters.rst b/docs/romanisim/parameters.rst index 0e52105f..72549cc6 100644 --- a/docs/romanisim/parameters.rst +++ b/docs/romanisim/parameters.rst @@ -15,6 +15,7 @@ telescope. These include: which to place the given ra/dec * the default persistence parameters * the default cosmic ray parameters +* the default gain when CRDS is not used These values can be overridden by specifying a yaml config file on the command line to romanisim-make-image. diff --git a/romanisim/__init__.py b/romanisim/__init__.py index 59c6a2ea..04668334 100755 --- a/romanisim/__init__.py +++ b/romanisim/__init__.py @@ -15,8 +15,7 @@ import logging log = logging.getLogger(__name__) -# logging.basicConfig(format='%(asctime)s %(levelname)-8s %(message)s', -# datefmt='%Y-%m-%d %H:%M:%S') -log.setLevel(logging.INFO) +logging.basicConfig(format='%(asctime)s %(levelname)-8s %(message)s', + datefmt='%Y-%m-%d %H:%M:%S', level=logging.INFO) __version__ = version(__name__) diff --git a/romanisim/image.py b/romanisim/image.py index 617710bf..1f5e9cda 100644 --- a/romanisim/image.py +++ b/romanisim/image.py @@ -519,8 +519,9 @@ def simulate_counts(metadata, objlist, catalog of simulated objects in image """ - read_pattern = parameters.read_pattern[ - metadata['exposure']['ma_table_number']] + read_pattern = metadata['exposure'].get( + 'read_pattern', + parameters.read_pattern[metadata['exposure']['ma_table_number']]) sca = int(metadata['instrument']['detector'][3:]) exptime = parameters.read_time * read_pattern[-1][-1] @@ -692,6 +693,7 @@ def simulate(metadata, objlist, * sca: metadata['instrument']['detector'] * bandpass: metadata['instrument']['optical_detector'] * ma_table_number: metadata['exposure']['ma_table_number'] + * read_pattern: metadata['exposure']['read_pattern'] objlist : list[CatalogObject] or Table List of objects in the field to simulate @@ -746,10 +748,11 @@ def simulate(metadata, objlist, image_node['meta'] = meta image_mod = roman_datamodels.datamodels.ImageModel(image_node) - ma_table_number = image_mod.meta.exposure.ma_table_number filter_name = image_mod.meta.instrument.optical_element - read_pattern = parameters.read_pattern[ma_table_number] + read_pattern = metadata['exposure'].get( + 'read_pattern', + parameters.read_pattern[metadata['exposure']['ma_table_number']]) refdata = gather_reference_data(image_mod, usecrds=usecrds) read_noise = refdata['readnoise'] @@ -781,7 +784,7 @@ def simulate(metadata, objlist, im = dict(data=counts.array, meta=dict(image_mod.meta.items())) else: l1, l1dq = romanisim.l1.make_l1( - counts, ma_table_number, read_noise=read_noise, + counts, read_pattern, read_noise=read_noise, pedestal_extra_noise=pedestal_extra_noise, rng=rng, gain=gain, crparam=crparam, diff --git a/romanisim/ris_make_utils.py b/romanisim/ris_make_utils.py index 1100f6b1..67aa9686 100755 --- a/romanisim/ris_make_utils.py +++ b/romanisim/ris_make_utils.py @@ -150,7 +150,7 @@ def create_catalog(metadata=None, catalog_name=None, bandpasses=['F087'], cat = catalog.make_dummy_table_catalog( coord, bandpasses=bandpasses, nobj=nobj, rng=rng) else: - cat = table.Table.read(catalog_name, comment="#", delimiter=" ") + cat = table.Table.read(catalog_name) bandpass = [f for f in cat.dtype.names if f[0] == 'F'] bad = np.zeros(len(cat), dtype='bool') for b in bandpass: diff --git a/romanisim/util.py b/romanisim/util.py index 712f3ea1..a2c00415 100644 --- a/romanisim/util.py +++ b/romanisim/util.py @@ -186,8 +186,10 @@ def add_more_metadata(metadata): if 'exposure' not in metadata.keys(): metadata['exposure'] = {} - read_pattern = parameters.read_pattern[ - metadata['exposure']['ma_table_number']] + read_pattern = metadata['exposure'].get( + 'read_pattern', + parameters.read_pattern[metadata['exposure']['ma_table_number']]) + metadata['exposure']['read_pattern'] = read_pattern openshuttertime = parameters.read_time * read_pattern[-1][-1] offsets = dict(start=0 * u.s, mid=openshuttertime * u.s / 2, end=openshuttertime * u.s) @@ -212,7 +214,6 @@ def add_more_metadata(metadata): metadata['exposure']['exposure_time'] = openshuttertime metadata['exposure']['effective_exposure_time'] = openshuttertime metadata['exposure']['duration'] = openshuttertime - metadata['exposure']['read_pattern'] = read_pattern # integration_start? integration_end? nints = 1? ... if 'target' not in metadata.keys():