def draw_observations(self, lmin=None, lmax=None, properties=None, seed=None): """ Draws observations. The result is a signal and a list of simulated CmbObservation instances each corresponding to a set of observation properties. One must provide an lmax for the simulation. """ import healpix.resources from isotropic import ClArray from observation import load_temperature_pixel_window_matrix, CmbObservation from maps import random_real_harmonic_sphere_map try: iter(properties) except TypeError: properties = [properties] random_state = as_random_state(seed) Nside = min([x.Nside for x in properties]) if lmin is None: lmin = self.default_lmin(Nside) if lmax is None: lmax = self.default_lmax(Nside) # Simulate signal with the covariance of the model S = self.load_covariance(lmin, lmax) P, L = S.cholesky() z = random_real_harmonic_sphere_map(lmin, lmax, state=random_state) signal = P.H * (L * (P * z)) # Produce observations observations = [] for prop in properties: # First, smooth the signal with the beam smoothed_signal = signal smoothed_signal = prop.load_beam_transfer_matrix(lmin, lmax) * signal # Add the pixel window pixwin = load_temperature_pixel_window_matrix(prop.Nside, lmin, lmax) smoothed_signal = pixwin * smoothed_signal # Convert to pixel space and add noise map = smoothed_signal.to_pixel(Nside=prop.Nside) assert map.pixel_order == 'ring' rms = prop.load_rms('ring', include_added_noise=False) map += random_state.normal(scale=rms) observations.append(CmbObservation(temperature=map, properties=prop)) return signal, observations
def __init__(self, observations, model, lmin=None, lmax=None, lprecond=50, seed=None, logger=None, max_iterations=10000, eps=1e-6, norm_order=None, preconditioner=None, cache=None): # Check inputs, defaults if len(observations) != 1: raise NotImplementedError('Realization with more than one data band is ' 'not yet implemented') for o in observations: if not isinstance(o, CmbObservation): raise TypeError('observations: Please provide a list of CmbObservation instances') Nside = min([o.Nside for o in observations]) if any([o.Nside != Nside for o in observations]): raise NotImplementedError('Currently assumes a single Nside (for beams), trivial ' 'to fix though') self.random_state = as_random_state(seed) if lprecond is not None and preconditioner is not None: raise ValueError('Cannot provide both lprecond and preconditioner') if preconditioner is None: preconditioner = default_preconditioner(lprecond) if cache is None: cache = {} if lmin is None: lmin = model.default_lmin(Nside) if lmax is None: lmax = model.default_lmax(Nside) check_l_increases(lmin, lprecond, lmax) obs = observations[0] N_inv_map = obs.properties.load_Ninv_map_mutable('ring') beam_and_window = obs.properties.load_beam_transfer_matrix(lmin, lmax) # Multiply together beam and window pixwin = load_temperature_pixel_window_matrix(Nside, lmin, lmax) beam_and_window = pixwin * beam_and_window del pixwin if logger is None: logger = logging.getLogger('cmb.cr') logger.setLevel(logging.INFO) self.eps = eps self.observations = observations self.lmin = lmin self.lmax = lmax self.Npix = N_inv_map.Npix self.N_inv_map = N_inv_map self.Nside = N_inv_map.Nside self.uniform_noise = np.all(N_inv_map == N_inv_map[0]) self.logger = logger self.preconditioner = preconditioner self.beam_and_window = beam_and_window # Compute N^{-1}d in harmonic space right away self.scaled_Ninv_map = N_inv_map * (self.Npix / 4 / np.pi) d = obs.load_temperature_mutable('ring') scaled_Ninv_d = self.scaled_Ninv_map * d self.Ninv_d = scaled_Ninv_d.to_harmonic(lmin, lmax, use_weights=False).to_real() preconditioner.set_logger(make_sublogger(logger, 'precond')) preconditioner.set_l_range(lmin, lmax) preconditioner.set_cache(cache) preconditioner.set_experiment_properties([o.properties for o in observations]) if model is not None: self.set_model(model)