diff --git a/docs/ghosts.rst b/docs/ghosts.rst index 185b22295..1ceb7d343 100644 --- a/docs/ghosts.rst +++ b/docs/ghosts.rst @@ -30,7 +30,7 @@ If **add_ghosts** is True, Mirage will calculate, for each point source in your .. tip:: - If you wish to run Mirage with a "gap summary" file other than that in the config directory, you can either replace the file in the config directory with your own, or update the value of NIRISS_GHOST_GAP_FILE in the constants.py file of the repository to point to your file. This may be useful for testing new ghost position calibration results. + The current "gap summary" file allows for the addition of ghost sources for observations that use F090W, F115W, F140M, F150W, and F200W. For other filters, the ghost positions and/or magnitudes have not been characterized, and therefore ghosts will not be added. If you wish to run Mirage with a "gap summary" file other than that in the config directory, you can either replace the file in the config directory with your own, or update the value of NIRISS_GHOST_GAP_FILE in the constants.py file of the repository to point to your file. This may be useful for testing new ghost position calibration results. Mirage currently carries one fits file in its collection of :ref:`reference files ` that provides an image of an optical ghost from a point source on the NIRISS detector. This image was created from ground testing data. By default, this file is used when adding ghosts to the data. **NOTE that this stamp image applies to point sources only. By default, no ghosts are added for galaxy or extended sources.** diff --git a/mirage/seed_image/catalog_seed_image.py b/mirage/seed_image/catalog_seed_image.py index 663abb74a..66457987b 100755 --- a/mirage/seed_image/catalog_seed_image.py +++ b/mirage/seed_image/catalog_seed_image.py @@ -1626,7 +1626,8 @@ def movingTargetInputs(self, filename, input_type, MT_tracking=False, # frame individually. if add_ghosts: ghost_x_frames, ghost_y_frames, ghost_mags, ghost_countrate, ghost_file = self.locate_ghost(x_frames, y_frames, rate, - magsys, entry, input_type) + magsys, entry, input_type, + log_skipped_filters=False) if ghost_file is not None: ghost_stamp, ghost_header = self.basic_get_image(ghost_file) @@ -2677,7 +2678,8 @@ def get_point_source_list(self, filename, source_type='pointsources', segment_of # If this is a NIRISS simulation and the user wants to add ghosts, # do that here. if self.params['Inst']['instrument'].lower() == 'niriss' and self.params['simSignals']['add_ghosts']: - gx, gy, gmag, gcounts, gfile = self.locate_ghost(pixelx, pixely, countrate, magsys, values, 'point_source') + gx, gy, gmag, gcounts, gfile = self.locate_ghost(pixelx, pixely, countrate, magsys, values, 'point_source', + log_skipped_filters=log_ghost_err) if np.isfinite(gx) and gfile is not None: ghost_source_index.append(index) ghost_x.append(gx) @@ -2686,14 +2688,17 @@ def get_point_source_list(self, filename, source_type='pointsources', segment_of ghost_filename.append(gfile) ghost_src, skipped_non_niriss = source_mags_to_ghost_mags(values, self.params['Reffiles']['flux_cal'], - magsys, NIRISS_GHOST_GAP_FILE, log_skipped_filters=log_ghost_err) - ghost_i += 1 + magsys, NIRISS_GHOST_GAP_FILE, log_skipped_filters=False) if ghost_mags is None: ghost_mags = copy.deepcopy(ghost_src) else: ghost_mags = vstack([ghost_mags, ghost_src]) + # Increment the counter to control the logging regardless of whether the source + # is on the detector or not. + ghost_i += 1 + psf_len = self.find_psf_size(countrate) edgex = np.int(psf_len // 2) edgey = np.int(psf_len // 2) @@ -3920,7 +3925,8 @@ def filterGalaxyList(self, galaxylist, pixelflag, radiusflag, magsystem, catfile # If this is a NIRISS simulation and the user wants to add ghosts, # do that here. if self.params['Inst']['instrument'].lower() == 'niriss' and self.params['simSignals']['add_ghosts']: - gx, gy, gmag, gcounts, gfile = self.locate_ghost(pixelx, pixely, rate, magsystem, source, 'galaxies') + gx, gy, gmag, gcounts, gfile = self.locate_ghost(pixelx, pixely, rate, magsystem, source, 'galaxies', + log_skipped_filters=log_ghost_err) if np.isfinite(gx) and gfile is not None: ghost_source_index.append(index) ghost_x.append(gx) @@ -3929,14 +3935,17 @@ def filterGalaxyList(self, galaxylist, pixelflag, radiusflag, magsystem, catfile ghost_filename.append(gfile) ghost_src, skipped_non_niriss = source_mags_to_ghost_mags(source, self.params['Reffiles']['flux_cal'], magsystem, - NIRISS_GHOST_GAP_FILE, log_skipped_filters=log_ghost_err) - ghost_i += 1 + NIRISS_GHOST_GAP_FILE, log_skipped_filters=False) if ghost_mags is None: ghost_mags = copy.deepcopy(ghost_src) else: ghost_mags = vstack([ghost_mags, ghost_src]) + # Increment the counter to control the logging regardless of whether the source + # is on the detector or not. + ghost_i += 1 + # only keep the source if the peak will fall within the subarray if pixely > outminy and pixely < outmaxy and pixelx > outminx and pixelx < outmaxx: @@ -4328,7 +4337,7 @@ def calc_x_position_angle(self, v2_value, v3_value, position_angle): + 90. - self.params['Telescope']['rotation']) return x_posang - def locate_ghost(self, pixel_x, pixel_y, count_rate, magnitude_system, source_row, obj_type): + def locate_ghost(self, pixel_x, pixel_y, count_rate, magnitude_system, source_row, obj_type, log_skipped_filters=True): """Calculate the ghost location, brightness, and stamp image file name for the input source. @@ -4368,6 +4377,10 @@ def locate_ghost(self, pixel_x, pixel_y, count_rate, magnitude_system, source_ro ghost_file : str Name of fits file containing the stamp image to use for the ghost source + + log_skipped_filters : bool + If True, any filter magnitudes that are not converted because + the filter is not in the gap summary file will be logged. """ allowed_types = ['point_source', 'galaxies', 'extended'] if obj_type not in allowed_types: @@ -4382,7 +4395,8 @@ def locate_ghost(self, pixel_x, pixel_y, count_rate, magnitude_system, source_ro count_rate, search_filter, self.params['Readout']['pupil'], - NIRISS_GHOST_GAP_FILE + NIRISS_GHOST_GAP_FILE, + log_skipped_filters=log_skipped_filters ) if isinstance(ghost_pixelx, np.float): if not np.isfinite(ghost_pixelx): @@ -4629,7 +4643,8 @@ def getExtendedSourceList(self, filename, ghost_search=True): # This is done outside the if statement below because sources outside the # detector can potentially produce ghosts on the detector if ghost_search and self.params['Inst']['instrument'].lower() == 'niriss' and self.params['simSignals']['add_ghosts']: - gx, gy, gmag, gcounts, gfile = self.locate_ghost(pixelx, pixely, countrate, magsys, values, 'extended') + gx, gy, gmag, gcounts, gfile = self.locate_ghost(pixelx, pixely, countrate, magsys, values, 'extended', + log_skipped_filters=log_ghost_err) if np.isfinite(gx) and gfile is not None: ghost_source_index.append(indexnum) ghost_x.append(gx) @@ -4638,14 +4653,17 @@ def getExtendedSourceList(self, filename, ghost_search=True): ghost_filename.append(gfile) ghost_src, skipped_non_niriss = source_mags_to_ghost_mags(values, self.params['Reffiles']['flux_cal'], - magsys, NIRISS_GHOST_GAP_FILE, log_skipped_filters=log_ghost_err) - ghost_i += 1 + magsys, NIRISS_GHOST_GAP_FILE, log_skipped_filters=False) if ghost_mags is None: ghost_mags = copy.deepcopy(ghost_src) else: ghost_mags = vstack([ghost_mags, ghost_src]) + # Increment the counter to control the logging regardless of whether the source + # is on the detector or not. + ghost_i += 1 + # Keep only sources within the appropriate bounds if pixely > miny and pixely < maxy and pixelx > minx and pixelx < maxx: