def generate_batch_spectrum(self, param_vector, noise=True): line_vec = (6302.5, 2.5, 1) line_arg = 1000 * (np.linspace(6302.0692255, 6303.2544205, 56) - line_vec[0]) spectrum = me_model(param_vector, line_arg, line_vec, with_ff=True, with_noise=noise) cont = param_vector[:, 6] + line_vec[2] * param_vector[:, 7] cont = cont * np.amax(spectrum.reshape(-1, 224), axis=1) / self.hps.cont_scale cont = torch.from_numpy(cont.reshape(-1, 1)).float().to(self.device) y = normalize_output(param_vector, mode=self.hps.mode, logB=self.hps.logB) y = torch.from_numpy(y).float().to(self.device) if 'rescale' in self.hps.transform_type: rescaled = (np.swapaxes(spectrum, 0, 2) * np.array(self.hps.factors).reshape(4, 1, 1)).swapaxes( 0, 2) if 'mlp' in self.hps.transform_type: rescaled = rescaled.reshape(-1, 224, order='F') rescaled = torch.from_numpy(rescaled).float().to(self.device) else: NotImplementedError('Only rescale transform') data = {'X': [rescaled, cont], 'Y': y} return data
def compute_mean_spectrum(filename, batch_size=None, nbatches=None): line_vec = (6302.5, 2.5, 1) line_arg = 1000 * (np.linspace(6302.0692255, 6303.2544205, 56) - line_vec[0]) # filename = '/Users/irinaknyazeva/Projects/Solar/InverseProblem/data/parameters_base.fits' parameter_base = fits.open(filename)[0].data cont_vec = parameter_base[:, 6] + line_vec[2] * parameter_base[:, 7] N = parameter_base.shape[0] if batch_size is None: batch_size = 10 if nbatches is None: nbatches = min(2, N // batch_size - 1) mean_spectrum = np.zeros((nbatches, 224)) max_spectrum = np.zeros((nbatches, 224)) min_spectrum = np.zeros((nbatches, 224)) std_spectrum = np.zeros((nbatches, 224)) for idx in tqdm(range(nbatches)): param_vec = parameter_base[idx * batch_size: idx * batch_size + batch_size, :] spectrum = me_model(param_vec, line_arg, line_vec, with_ff=True).reshape((-1, 224), order='F') mean_spectrum[idx, :] = spectrum.mean(axis=0) max_spectrum[idx, :] = spectrum.max(axis=0) min_spectrum[idx, :] = spectrum.min(axis=0) std_spectrum[idx, :] = spectrum.std(axis=0) spectrum_dict = {'mean': mean_spectrum.mean(axis=0), 'max': max_spectrum.max(axis=0), 'min': min_spectrum.min(axis=0), 'std': std_spectrum.mean(axis=0), 'cont_mean': np.mean(cont_vec), 'cont_std': np.std(cont_vec)} return spectrum_dict
def test_me_model_with_noise(self, param_vec_0): line_vec = (6302.5, 2.5, 1) line_arg = 1000 * (np.linspace(6302.0692255, 6303.2544205, 56) - line_vec[0]) spectrum_no_noise = me_model(param_vec_0[0], line_arg, line_vec, with_ff=True, with_noise=False) spectrum_with_noise = me_model(param_vec_0[0], line_arg, line_vec, with_ff=True, with_noise=True) signal_to_noise = np.mean(spectrum_with_noise / spectrum_no_noise, axis=1) assert np.mean(signal_to_noise, axis=1) < 1000
def test_me_model_no_noise(self): line_vec = (6302.5, 2.5, 1) line_arg = 1000 * (np.linspace(6302.0692255, 6303.2544205, 56) - line_vec[0]) # with stray shift param_vec = [1000., 15., 20., 30., 1., 50., 0.5, 0.5, 0, 0.7, -9] spectrum = me_model(param_vec, line_arg, line_vec, with_ff=False, with_noise=False) spectrum_ff = me_model(param_vec, line_arg, line_vec, with_ff=True, with_noise=False) expected_ff_I = [0.91103614, 0.90068347, 0.88866059] expected_ff_QUV = [0.00003492, 0.00002593, 0.00785174] assert expected_ff_I == pytest.approx(spectrum_ff[0, :3, 0], rel=1e-4) assert expected_ff_QUV == pytest.approx(spectrum_ff[0, 0, 1:4], rel=1e-3)
def test_me_batch(self): parameters = np.array( [[1000, 15, 20, 30, 1, 50, 0.5, 0.5, 0, 0.7, -9], [1000, 15, 20, 30, 1, 50, 0.5, 0.5, 0, 0.7, -4.25], [1000, 15, 20, 30, 1, 50, 0.5, 0.5, 0, 0.7, 0.5]]) line_vec = (6302.5, 2.5, 1) line_arg = 1000 * (np.linspace(6302.0692255, 6303.2544205, 56) - line_vec[0]) spectrum = me_model(parameters, line_arg, line_vec, with_ff=True, with_noise=False) expected_I = [0.91103614, 0.92981541, 0.93938165] expected_QUV = [0.00003492, 0.00002593, 0.00785174] assert expected_I == pytest.approx(spectrum[:, 0, 0]) assert expected_QUV == pytest.approx(spectrum[0, 0, 1:], rel=1e-3) assert spectrum.shape == (3, 56, 4)
def lm_inversion(spectrum, initial='mean', line_arg=None, line_vec=None): if not line_vec: line_vec = (6302.5, 2.5, 1) if not line_arg: line_arg = 1000 * (np.linspace(6302.0692255, 6303.2544205, 56) - line_vec[0]) lower_bounds = np.array([0, 0, 0, 5, 0.1, 0.01, 0.01, 0.01, -20, 0, -20]) upper_bounds = ([5000, 180, 180, 100, 2, 100, 1, 1, 20, 1, 20]) if initial == 'mean': x0 = [1000, 45, 45, 30, 1, 10, 0.5, 0.5, 0, 0.5, 0] elif initial == 'random': x0 = lower_bounds + np.random.random(size=11) * (upper_bounds - lower_bounds) else: raise fun = lambda x: np.power(me_model(x, line_arg=line_arg, line_vec=line_vec, with_ff=True, with_noise=False, cont=1) - spectrum, 2).flatten() params = scipy.optimize.least_squares(fun, x0=x0, method='lm') return params.x