def _sky_brightness_cps(self): """ :return: sky brightness in electrons per second """ cps = data_util.magnitude2cps(self._sky_brightness, magnitude_zero_point=self._magnitude_zero_point) return cps
def test_magnitude2cps(): mag_zero_point = 30 cps = 100 magnitude = data_util.cps2magnitude(cps, magnitude_zero_point=mag_zero_point) cps_new = data_util.magnitude2cps(magnitude, magnitude_zero_point=mag_zero_point) npt.assert_almost_equal(cps, cps_new, decimal=9)
def test_log_likelihood(self): ddt = 1000 # time-delay distance in units Mpc num = 4 magnification_model = np.ones(num) magnitude_intrinsic = 19 magnitude_zero_point = 20 amp_int = magnitude2cps(magnitude=magnitude_intrinsic, magnitude_zero_point=magnitude_zero_point) amp_measured = magnification_model * amp_int cov_amp_measured = np.diag((amp_measured / 10)**2) time_delay_measured = np.ones(num - 1) * 10 cov_td_measured = np.ones((num - 1, num - 1)) fermat_unit_conversion = const.Mpc / const.c / const.day_s * const.arcsec**2 fermat_diff = time_delay_measured / fermat_unit_conversion / ddt model_vector = np.append(fermat_diff, magnification_model) cov_model = np.diag((model_vector / 10)**2) # un-normalized likelihood likelihood = TDMagLikelihood(time_delay_measured, cov_td_measured, amp_measured, cov_amp_measured, fermat_diff, magnification_model, cov_model, magnitude_zero_point=magnitude_zero_point) logl = likelihood.log_likelihood(ddt=ddt, mu_intrinsic=magnitude_intrinsic) model_vector, cov_tot = likelihood._model_cov( ddt, mu_intrinsic=magnitude_intrinsic) sign_det, lndet = np.linalg.slogdet(cov_tot) logl_norm = -1 / 2. * (likelihood.num_data * np.log(2 * np.pi) + lndet) npt.assert_almost_equal(logl, logl_norm, decimal=6) num = 4 magnification_model = np.ones(num) cov_td_measured = np.zeros((num - 1, num - 1)) cov_amp_measured = np.zeros((num, num)) amp_int = 10 amp_measured = magnification_model * amp_int cov_model = np.zeros((num + num - 1, num + num - 1)) likelihood = TDMagLikelihood(time_delay_measured, cov_td_measured, amp_measured, cov_amp_measured, fermat_diff, magnification_model, cov_model, magnitude_zero_point=magnitude_zero_point) logl = likelihood.log_likelihood(ddt=ddt, mu_intrinsic=1) assert logl == -np.inf
def sky_brightness(self): """ :return: sky brightness (counts per square arcseconds in unit of data) """ cps = data_util.magnitude2cps( self._sky_brightness, magnitude_zero_point=self._magnitude_zero_point) if self._data_count_unit == 'e-': cps *= self.ccd_gain return cps
def sky_brightness(self): """ :return: sky brightness (counts per square arcseconds in unit of data) """ if self._sky_brightness is None: raise ValueError('sky_brightness is not set in the class instance!') cps = data_util.magnitude2cps(self._sky_brightness, magnitude_zero_point=self._magnitude_zero_point) if self._data_count_unit == 'e-': cps *= self.ccd_gain return cps
def test_displace_prediction(self): ddt, dd = 1, 1 mag_source = 16 magnitude_zero_point = 20 amp_source = magnitude2cps(magnitude=mag_source, magnitude_zero_point=magnitude_zero_point) # case where nothing happens ddt_, dd_, mag_source_ = self.transform.displace_prediction(ddt, dd, gamma_ppn=1, lambda_mst=1, kappa_ext=0, mag_source=mag_source) assert ddt == ddt_ assert dd == dd_ assert mag_source_ == mag_source # case where kappa_ext is displaced kappa_ext = 0.1 ddt_, dd_, mag_source_ = self.transform.displace_prediction(ddt, dd, gamma_ppn=1, lambda_mst=1, kappa_ext=kappa_ext, mag_source=mag_source) assert ddt_ == ddt * (1 - kappa_ext) assert dd_ == dd amp_source_ = magnitude2cps(magnitude=mag_source_, magnitude_zero_point=magnitude_zero_point) assert amp_source_ == amp_source / (1 - kappa_ext)**2 # case where lambda_mst is displaced lambda_mst = 0.9 ddt_, dd_, mag_source_ = self.transform.displace_prediction(ddt, dd, gamma_ppn=1, lambda_mst=lambda_mst, kappa_ext=0, mag_source=mag_source) assert ddt_ == ddt * lambda_mst assert dd == dd_ amp_source_ = magnitude2cps(magnitude=mag_source_, magnitude_zero_point=magnitude_zero_point) assert amp_source_ == amp_source / lambda_mst ** 2 # case for gamma_ppn gamma_ppn = 1.1 ddt_, dd_, mag_source_ = self.transform.displace_prediction(ddt, dd, gamma_ppn=gamma_ppn, lambda_mst=1, kappa_ext=0, mag_source=mag_source) assert ddt_ == ddt assert dd_ == dd * (1 + gamma_ppn) / 2. assert mag_source_ == mag_source
def _scale_model(self, mu_intrinsic): """ :param mu_intrinsic: intrinsic brightness of the source (already incorporating the inverse MST transform) :return: """ amp_intrinsic = magnitude2cps( magnitude=mu_intrinsic, magnitude_zero_point=self._magnitude_zero_point) # compute model predicted magnified image amplitude and time delay model_vector = amp_intrinsic * self._mean_magnification_model # scale model covariance matrix with model_scale vector (in quadrature) cov_model = self._cov_magnification_model * amp_intrinsic**2 # combine data and model covariance matrix cov_tot = self._cov_amp_measured + cov_model return model_vector, cov_tot
def magnitude2cps(self, magnitude): """ converts an apparent magnitude to counts per second (in units of the data) The zero point of an instrument, by definition, is the magnitude of an object that produces one count (or data number, DN) per second. The magnitude of an arbitrary object producing DN counts in an observation of length EXPTIME is therefore: m = -2.5 x log10(DN / EXPTIME) + ZEROPOINT :param magnitude: magnitude of object :return: counts per second of object """ # compute counts in units of ADS (as magnitude zero point is defined) cps = data_util.magnitude2cps(magnitude, magnitude_zero_point=self._magnitude_zero_point) if self._data_count_unit == 'ADU': cps /= self.ccd_gain return cps
def _model_cov(self, ddt, mu_intrinsic): """ :param ddt: time-delay distance (physical Mpc) :param mu_intrinsic: intrinsic brightness of the source (already incorporating the inverse MST transform) :return: """ # compute model predicted magnified image amplitude and time delay amp_intrinsic = magnitude2cps( magnitude=mu_intrinsic, magnitude_zero_point=self._magnitude_zero_point) model_scale = np.append( ddt * self._fermat_unit_conversion * np.ones(self._n_td), amp_intrinsic * np.ones(self._n_amp)) model_vector = model_scale * self._model_tot # scale model covariance matrix with model_scale vector (in quadrature) cov_model = model_scale * (self._cov_model * model_scale).T # combine data and model covariance matrix cov_tot = self._cov_data + cov_model return model_vector, cov_tot
def test_log_likelihood(self): num = 4 magnitude_intrinsic = 19 magnitude_zero_point = 20 amp_int = magnitude2cps(magnitude=magnitude_intrinsic, magnitude_zero_point=magnitude_zero_point) magnification_model = np.ones(num) magnification_model_cov = np.diag((magnification_model / 10)**2) magnitude_measured = magnification_model * amp_int magnitude_measured_cov = np.diag((magnitude_measured / 10)**2) # un-normalized likelihood likelihood = MagnificationLikelihood( amp_measured=magnitude_measured, cov_amp_measured=magnitude_measured_cov, magnification_model=magnification_model, cov_magnification_model=magnification_model_cov, magnitude_zero_point=magnitude_zero_point) logl = likelihood.log_likelihood(mu_intrinsic=magnitude_intrinsic) _, cov_tot = likelihood._scale_model(mu_intrinsic=magnitude_intrinsic) sign_det, lndet = np.linalg.slogdet(cov_tot) logl_test = -1 / 2. * (likelihood.num_data * np.log(2 * np.pi) + lndet) npt.assert_almost_equal(logl, logl_test, decimal=6) num = 4 magnification_model = np.ones(num) magnification_model_cov = np.zeros((num, num)) amp_int = 10 magnitude_measured = magnification_model * amp_int magnitude_measured_cov = np.zeros((num, num)) likelihood = MagnificationLikelihood( amp_measured=magnitude_measured, cov_amp_measured=magnitude_measured_cov, magnification_model=magnification_model, cov_magnification_model=magnification_model_cov) logl = likelihood.log_likelihood(mu_intrinsic=1) assert logl == -np.inf
def __init__(self, pixel_scale, exposure_time, magnitude_zero_point, read_noise=None, ccd_gain=None, sky_brightness=None, seeing=None, num_exposures=1, psf_type='GAUSSIAN', kernel_point_source=None, truncation=5, data_count_unit='ADU', background_noise=None): """ Parameters ---------- pixel_scale : float pixel scale in arcsec/pixel exposure_time : float exposure time per image in seconds magnitude_zero_point : float magnitude at which 1 count per second per arcsecond square is registered read_noise : float std of noise generated by readout (in units of electrons) ccd_gain : float electrons/ADU (analog-to-digital unit). A gain of 8 means that the camera digitizes the CCD signal so that each ADU corresponds to 8 photoelectrons sky_brightness : float sky brightness (in magnitude per square arcsec) seeing : float fwhm of PSF num_exposures : float number of exposures that are combined psf_type : str type of PSF ('GAUSSIAN' and 'PIXEL' supported) kernel_point_source : 2d numpy array model of PSF centered with odd number of pixels per axis(optional when psf_type='PIXEL' is chosen) truncation : float Gaussian truncation (in units of sigma), only required for 'GAUSSIAN' model data_count_unit : str unit of the data (and other properties), 'e-': (electrons assumed to be IID), 'ADU': (analog-to-digital unit) background_noise : float sqrt(variance of background) as a total contribution from read noise, sky brightness, etc. in units of the data_count_units If you set this parameter, it will override readout_noise, sky_brightness. Default: None """ self.pixel_scale = pixel_scale self.exposure_time = exposure_time self.magnitude_zero_point = magnitude_zero_point self.ccd_gain = ccd_gain self.sky_brightness = sky_brightness self.seeing = seeing self.num_exposures = num_exposures self.psf_type = psf_type self.kernel_point_source = kernel_point_source self.truncation = truncation self.data_count_unit = data_count_unit self.background_noise = background_noise #FIXME: seeing, psf_type, kernel_point_source, and truncation do not seem to be used at all. if self.background_noise is None: self.readout_noise = read_noise if self.data_count_unit == 'ADU': self.readout_noise /= self.ccd_gain self.sky_brightness = data_util.magnitude2cps( self.sky_brightness, self.magnitude_zero_point) if self.data_count_unit == 'ADU': self.sky_brightness /= self.ccd_gain self.exposure_time_tot = self.num_exposures * self.exposure_time self.readout_noise_tot = self.num_exposures * self.readout_noise**2.0 self.sky_per_pixel = self.sky_brightness * pixel_scale**2.0 self.get_background_noise_sigma2 = getattr( self, 'get_background_noise_sigma2_composite' ) if self.background_noise is None else getattr( self, 'get_background_noise_sigma2_simple') # For Poisson noise self.scaled_exposure_time = self.exposure_time_tot if self.data_count_unit == 'ADU': self.scaled_exposure_time *= self.ccd_gain