def convert_to_flam(magnitudes, param_tuple, magnitude_system): """Convert the magnitude values for a given magnitude column into units of f_lambda. Parameters ---------- magnitudes : list List of magnitude values to be converted param_tuple : tup Tuple of (photflam, photfnu, zeropoint, pivot_wavelength) for the filter corresponding to the input magnitudes magnitude_system : str Name of the magnitude system for the input magnitudes (e.g. 'abmag') Returns ------- flam : list List of f_lambda values corresponding to the list of input magnitudes """ photflam, photfnu, zeropoint, pivot = param_tuple if magnitude_system in ['stmag', 'vegamag']: countrate = magnitude_to_countrate('wfss', magnitude_system, magnitudes, photfnu=photfnu, photflam=photflam, vegamag_zeropoint=zeropoint) flam = countrate * photflam if magnitude_system == 'abmag': flam = 1. / (3.34e4 * pivot.to(u.AA).value**2) * 10**(-0.4*(magnitudes-8.9)) return flam
def convert_to_flam(instrument, filter_name, magnitudes, param_tuple, magnitude_system): """Convert the magnitude values for a given magnitude column into units of f_lambda. Parameters ---------- instrument : str e.g. 'nircam' filter_name : str Name of filter associated with observation. Only passed to ``magnitude_to_countrate`` where it is only used for scaling in the case of NIRISS filter wheel filters magnitudes : list List of magnitude values to be converted param_tuple : tup Tuple of (photflam, photfnu, zeropoint, pivot_wavelength) for the filter corresponding to the input magnitudes magnitude_system : str Name of the magnitude system for the input magnitudes (e.g. 'abmag') Returns ------- flam : list List of f_lambda values corresponding to the list of input magnitudes """ photflam, photfnu, zeropoint, pivot = param_tuple if magnitude_system in ['stmag', 'vegamag']: countrate = magnitude_to_countrate(instrument, filter_name, magnitude_system, magnitudes, photfnu=photfnu, photflam=photflam, vegamag_zeropoint=zeropoint) flam = countrate * photflam if magnitude_system == 'abmag': flam = 1. / (3.34e4 * pivot.to(u.AA).value**2) * 10**(-0.4 * (magnitudes - 8.9)) return flam
def source_mags_to_ghost_mags(row, flux_cal_file, magnitude_system, gap_summary_file, log_skipped_filters=False): """Works only for NIRISS. Given a row from a source catalog, create a ghost source catalog containing the magnitudes of the ghost associated with the source in all filters contained in the original catalog. Parameters ---------- row : astropy.table.Row Row containing a source from a source catalog flux_cal_file : str Name of file containing the flux calibration information for all filters magnitude_system : str Magnitude system of the magnitudes in the input catalog gap_summary_file : str Name of file that controls ghost locations relative to sources log_skipped_filters : bool If False, notices of skipped magnitude translations will not be logged. This is convenient for catalogs with lots of sources, because otherwise there can be many repeats of the message. Returns ------- ghost_row : astropy.table.Table Single row table containing the ghost magnitudes in all filters skipped_non_niriss_cols : bool If True, non NIRISS magnitude columns were found and skipped """ logger = logging.getLogger( 'mirage.ghosts.niriss_ghosts.source_mags_to_ghost_mags') mag_cols = [key for key in row.colnames if 'magnitude' in key] ghost_row = Table() skipped_non_niriss_cols = False for mag_col in mag_cols: # Ghost magnitudes can currently be calcuated only for NIRISS if 'nircam' in mag_col.lower() or 'fgs' in mag_col.lower(): skipped_non_niriss_cols = True continue col_parts = mag_col.split('_') if len(col_parts) == 3: filt = col_parts[1] else: raise ValueError( 'Unsupported magnitude column name for ghost conversion: {}'. format(mag_col)) wave = int(filt[1:4]) if wave > 200: filter_value = filt pupil_value = 'CLEARP' else: filter_value = 'CLEAR' pupil_value = filt # Get basic flux calibration information for the filter vegazeropoint, photflam, photfnu, pivot = \ fluxcal_info(flux_cal_file, 'niriss', filter_value, pupil_value, 'NIS', 'N') # Convert source magnitude to count rate mag = float(row[mag_col]) countrate = magnitude_to_countrate('niriss', filt, magnitude_system, mag, photfnu=photfnu, photflam=photflam, vegamag_zeropoint=vegazeropoint) # Get the count rate associated with the ghost _, _, ghost_countrate = get_ghost( 1024, 1024, countrate, filter_value, pupil_value, gap_summary_file, log_skipped_filters=log_skipped_filters) # Convert count rate to magnitude ghost_mag = countrate_to_magnitude('niriss', filt, magnitude_system, ghost_countrate, photfnu=photfnu, photflam=photflam, vegamag_zeropoint=vegazeropoint) ghost_row[mag_col] = [ghost_mag] return ghost_row, skipped_non_niriss_cols
def test_spectra_rescaling(): """Test the functionality for rescaling input spectra to a given magnitude in a given filter """ # JWST primary mirror area in cm^2. Needed for countrate check # at the end primary_area = 25.326 * (u.m * u.m) # Create spectrum: one source to be normalized # and the other should not be waves = np.arange(0.4, 5.6, 0.01) flux = np.repeat(1e-16, len(waves)) flux2 = np.repeat(4.24242424242e-18, len(waves)) # arbitrary value spectra = { 1: { "wavelengths": waves * u.micron, "fluxes": flux * u.pct }, 2: { "wavelengths": waves * u.micron, "fluxes": flux2 * units.FLAM } } # Create source catalog containing scaling info catalog = Table() catalog['index'] = [1, 2] catalog['nircam_f322w2_magnitude'] = [18.] * 2 catalog['niriss_f090w_magnitude'] = [18.] * 2 #catalog['fgs_magnitude'] = [18.] * 2 # Instrument info instrument = ['nircam', 'niriss'] # , 'fgs'] filter_name = ['F322W2', 'F090W'] # , 'N/A'] module = ['B', 'N'] # , 'F'] detector = ['NRCA1', 'NIS'] # , 'GUIDER1'] # Magnitude systems of renormalization magnitudes mag_sys = ['vegamag', 'abmag', 'stmag'] # Loop over options and test each for inst, filt, mod, det in zip(instrument, filter_name, module, detector): # Extract the appropriate column from the catalog information magcol = [col for col in catalog.colnames if inst in col] sub_catalog = catalog['index', magcol[0]] # Filter throughput files filter_thru_file = get_filter_throughput_file(instrument=inst, filter_name=filt, nircam_module=mod, fgs_detector=det) # Retrieve the correct gain value that goes with the fluxcal info if inst == 'nircam': gain = MEAN_GAIN_VALUES['nircam']['lwb'] elif inst == 'niriss': gain = MEAN_GAIN_VALUES['niriss'] elif inst == 'fgs': gain = MEAN_GAIN_VALUES['fgs'][det.lower()] # Create filter bandpass object, to be used in the final # comparison filter_tp = ascii.read(filter_thru_file) bp_waves = filter_tp['Wavelength_microns'].data * u.micron thru = filter_tp['Throughput'].data bandpass = SpectralElement( Empirical1D, points=bp_waves, lookup_table=thru) / gain # Check the renormalization in all photometric systems for magsys in mag_sys: rescaled_spectra = spec.rescale_normalized_spectra( spectra, sub_catalog, magsys, filter_thru_file, gain) # Calculate the countrate associated with the renormalized # spectrum through the requested filter for dataset in rescaled_spectra: if dataset == 1: # This block is for the spectra that are rescaled rescaled_spectrum = SourceSpectrum( Empirical1D, points=rescaled_spectra[dataset]['wavelengths'], lookup_table=rescaled_spectra[dataset]['fluxes']) obs = Observation(rescaled_spectrum, bandpass, binset=bandpass.waveset) renorm_counts = obs.countrate(area=primary_area) # Calculate the countrate associated with an object of # matching magnitude if inst != 'fgs': mag_col = '{}_{}_magnitude'.format( inst.lower(), filt.lower()) else: mag_col = 'fgs_magnitude' filt_info = spec.get_filter_info([mag_col], magsys) magnitude = catalog[mag_col][dataset - 1] photflam, photfnu, zeropoint, pivot = filt_info[mag_col] check_counts = magnitude_to_countrate( 'imaging', magsys, magnitude, photfnu=photfnu.value, photflam=photflam.value, vegamag_zeropoint=zeropoint) if magsys != 'vegamag': # As long as the correct gain is used, AB mag and ST mag # count rates agree very well tolerance = 0.0005 else: # Vegamag count rates for NIRISS have a sligtly larger # disagreement. Zeropoints were derived assuming Vega = 0.02 # magnitudes. This offset has been added to the rescaling # function, but may not be exact. tolerance = 0.0015 # This dataset has been rescaled, so check that the # countrate from the rescaled spectrum matches that from # the magnitude it was rescaled to if isinstance(check_counts, u.quantity.Quantity): check_counts = check_counts.value if isinstance(renorm_counts, u.quantity.Quantity): renorm_counts = renorm_counts.value print(inst, filt, magsys, renorm_counts, check_counts, renorm_counts / check_counts) assert np.isclose(renorm_counts, check_counts, atol=0, rtol=tolerance), \ print('Failed assertion: ', inst, filt, magsys, renorm_counts, check_counts, renorm_counts / check_counts) elif dataset == 2: # Not rescaled. In this case Mirage ignores the magnitude # value in the catalog, so we can't check against check_counts. # Just make sure that the rescaling function did not # change the spectrum at all assert np.all(spectra[dataset]['fluxes'] == rescaled_spectra[dataset]['fluxes'])