static void set_pixel(oskar_Sky* sky, int i, int x, int y, double val, const double crval[2], const double crpix[2], const double cdelt[2], double image_freq_hz, double spectral_index, int* status) { double ra, dec, l, m; /* Convert pixel positions to RA and Dec values. */ l = cdelt[0] * (x + 1 - crpix[0]); m = cdelt[1] * (y + 1 - crpix[1]); oskar_convert_relative_directions_to_lon_lat_2d_d(1, &l, &m, crval[0], crval[1], &ra, &dec); /* Store pixel data in sky model. */ if (oskar_sky_num_sources(sky) <= i) oskar_sky_resize(sky, i + 1000, status); oskar_sky_set_source(sky, i, ra, dec, val, 0.0, 0.0, 0.0, image_freq_hz, spectral_index, 0.0, 0.0, 0.0, 0.0, status); }
void oskar_sky_evaluate_gaussian_source_parameters(oskar_Sky* sky, int zero_failed_sources, double ra0, double dec0, int* num_failed, int* status) { int i, j, num_sources; int type; /* Check if safe to proceed. */ if (*status) return; /* Return if memory is not on the CPU. */ if (oskar_sky_mem_location(sky) != OSKAR_CPU) { *status = OSKAR_ERR_BAD_LOCATION; return; } /* Get data type and number of sources. */ type = oskar_sky_precision(sky); num_sources = oskar_sky_num_sources(sky); /* Switch on type. */ if (type == OSKAR_DOUBLE) { /* Double precision. */ const double *ra_, *dec_, *maj_, *min_, *pa_; double *I_, *Q_, *U_, *V_, *a_, *b_, *c_; double cos_pa_2, sin_pa_2, sin_2pa, inv_std_min_2, inv_std_maj_2; double ellipse_a, ellipse_b, maj, min, pa, cos_pa, sin_pa, t; double l[ELLIPSE_PTS], m[ELLIPSE_PTS]; double work1[5 * ELLIPSE_PTS], work2[5 * ELLIPSE_PTS]; double lon[ELLIPSE_PTS], lat[ELLIPSE_PTS]; double x[ELLIPSE_PTS], y[ELLIPSE_PTS], z[ELLIPSE_PTS]; ra_ = oskar_mem_double_const(oskar_sky_ra_rad_const(sky), status); dec_ = oskar_mem_double_const(oskar_sky_dec_rad_const(sky), status); maj_ = oskar_mem_double_const(oskar_sky_fwhm_major_rad_const(sky), status); min_ = oskar_mem_double_const(oskar_sky_fwhm_minor_rad_const(sky), status); pa_ = oskar_mem_double_const(oskar_sky_position_angle_rad_const(sky), status); I_ = oskar_mem_double(oskar_sky_I(sky), status); Q_ = oskar_mem_double(oskar_sky_Q(sky), status); U_ = oskar_mem_double(oskar_sky_U(sky), status); V_ = oskar_mem_double(oskar_sky_V(sky), status); a_ = oskar_mem_double(oskar_sky_gaussian_a(sky), status); b_ = oskar_mem_double(oskar_sky_gaussian_b(sky), status); c_ = oskar_mem_double(oskar_sky_gaussian_c(sky), status); for (i = 0; i < num_sources; ++i) { /* Note: could do something different from the projection below * in the case of a line (i.e. maj or min = 0), as in this case * there is no ellipse to project, only two points. * -- This continue could then be a if() .. else() instead. */ if (maj_[i] == 0.0 && min_[i] == 0.0) continue; /* Evaluate shape of ellipse on the l,m plane. */ ellipse_a = maj_[i]/2.0; ellipse_b = min_[i]/2.0; cos_pa = cos(pa_[i]); sin_pa = sin(pa_[i]); for (j = 0; j < ELLIPSE_PTS; ++j) { t = j * 60.0 * M_PI / 180.0; l[j] = ellipse_a*cos(t)*sin_pa + ellipse_b*sin(t)*cos_pa; m[j] = ellipse_a*cos(t)*cos_pa - ellipse_b*sin(t)*sin_pa; } oskar_convert_relative_directions_to_lon_lat_2d_d(ELLIPSE_PTS, l, m, 0.0, 0.0, lon, lat); /* Rotate on the sphere. */ oskar_convert_lon_lat_to_xyz_d(ELLIPSE_PTS, lon, lat, x, y, z); oskar_rotate_sph_d(ELLIPSE_PTS, x, y, z, ra_[i], dec_[i]); oskar_convert_xyz_to_lon_lat_d(ELLIPSE_PTS, x, y, z, lon, lat); oskar_convert_lon_lat_to_relative_directions_2d_d( ELLIPSE_PTS, lon, lat, ra0, dec0, l, m); /* Get new major and minor axes and position angle. */ oskar_fit_ellipse_d(&maj, &min, &pa, ELLIPSE_PTS, l, m, work1, work2, status); /* Check if fitting failed. */ if (*status == OSKAR_ERR_ELLIPSE_FIT_FAILED) { if (zero_failed_sources) { I_[i] = 0.0; Q_[i] = 0.0; U_[i] = 0.0; V_[i] = 0.0; } ++(*num_failed); *status = 0; continue; } else if (*status) break; /* Evaluate ellipse parameters. */ inv_std_maj_2 = 0.5 * (maj * maj) * M_PI_2_2_LN_2; inv_std_min_2 = 0.5 * (min * min) * M_PI_2_2_LN_2; cos_pa_2 = cos(pa) * cos(pa); sin_pa_2 = sin(pa) * sin(pa); sin_2pa = sin(2.0 * pa); a_[i] = cos_pa_2*inv_std_min_2 + sin_pa_2*inv_std_maj_2; b_[i] = -sin_2pa*inv_std_min_2*0.5 + sin_2pa *inv_std_maj_2*0.5; c_[i] = sin_pa_2*inv_std_min_2 + cos_pa_2*inv_std_maj_2; } } else { /* Single precision. */ const float *ra_, *dec_, *maj_, *min_, *pa_; float *I_, *Q_, *U_, *V_, *a_, *b_, *c_; float cos_pa_2, sin_pa_2, sin_2pa, inv_std_min_2, inv_std_maj_2; float ellipse_a, ellipse_b, maj, min, pa, cos_pa, sin_pa, t; float l[ELLIPSE_PTS], m[ELLIPSE_PTS]; float work1[5 * ELLIPSE_PTS], work2[5 * ELLIPSE_PTS]; float lon[ELLIPSE_PTS], lat[ELLIPSE_PTS]; float x[ELLIPSE_PTS], y[ELLIPSE_PTS], z[ELLIPSE_PTS]; ra_ = oskar_mem_float_const(oskar_sky_ra_rad_const(sky), status); dec_ = oskar_mem_float_const(oskar_sky_dec_rad_const(sky), status); maj_ = oskar_mem_float_const(oskar_sky_fwhm_major_rad_const(sky), status); min_ = oskar_mem_float_const(oskar_sky_fwhm_minor_rad_const(sky), status); pa_ = oskar_mem_float_const(oskar_sky_position_angle_rad_const(sky), status); I_ = oskar_mem_float(oskar_sky_I(sky), status); Q_ = oskar_mem_float(oskar_sky_Q(sky), status); U_ = oskar_mem_float(oskar_sky_U(sky), status); V_ = oskar_mem_float(oskar_sky_V(sky), status); a_ = oskar_mem_float(oskar_sky_gaussian_a(sky), status); b_ = oskar_mem_float(oskar_sky_gaussian_b(sky), status); c_ = oskar_mem_float(oskar_sky_gaussian_c(sky), status); for (i = 0; i < num_sources; ++i) { /* Note: could do something different from the projection below * in the case of a line (i.e. maj or min = 0), as in this case * there is no ellipse to project, only two points. * -- This continue could then be a if() .. else() instead. */ if (maj_[i] == 0.0 && min_[i] == 0.0) continue; /* Evaluate shape of ellipse on the l,m plane. */ ellipse_a = maj_[i]/2.0; ellipse_b = min_[i]/2.0; cos_pa = cos(pa_[i]); sin_pa = sin(pa_[i]); for (j = 0; j < ELLIPSE_PTS; ++j) { t = j * 60.0 * M_PI / 180.0; l[j] = ellipse_a*cos(t)*sin_pa + ellipse_b*sin(t)*cos_pa; m[j] = ellipse_a*cos(t)*cos_pa - ellipse_b*sin(t)*sin_pa; } oskar_convert_relative_directions_to_lon_lat_2d_f(ELLIPSE_PTS, l, m, 0.0, 0.0, lon, lat); /* Rotate on the sphere. */ oskar_convert_lon_lat_to_xyz_f(ELLIPSE_PTS, lon, lat, x, y, z); oskar_rotate_sph_f(ELLIPSE_PTS, x, y, z, ra_[i], dec_[i]); oskar_convert_xyz_to_lon_lat_f(ELLIPSE_PTS, x, y, z, lon, lat); oskar_convert_lon_lat_to_relative_directions_2d_f( ELLIPSE_PTS, lon, lat, (float)ra0, (float)dec0, l, m); /* Get new major and minor axes and position angle. */ oskar_fit_ellipse_f(&maj, &min, &pa, ELLIPSE_PTS, l, m, work1, work2, status); /* Check if fitting failed. */ if (*status == OSKAR_ERR_ELLIPSE_FIT_FAILED) { if (zero_failed_sources) { I_[i] = 0.0; Q_[i] = 0.0; U_[i] = 0.0; V_[i] = 0.0; } ++(*num_failed); *status = 0; continue; } else if (*status) break; /* Evaluate ellipse parameters. */ inv_std_maj_2 = 0.5 * (maj * maj) * M_PI_2_2_LN_2; inv_std_min_2 = 0.5 * (min * min) * M_PI_2_2_LN_2; cos_pa_2 = cos(pa) * cos(pa); sin_pa_2 = sin(pa) * sin(pa); sin_2pa = sin(2.0 * pa); a_[i] = cos_pa_2*inv_std_min_2 + sin_pa_2*inv_std_maj_2; b_[i] = -sin_2pa*inv_std_min_2*0.5 + sin_2pa *inv_std_maj_2*0.5; c_[i] = sin_pa_2*inv_std_min_2 + cos_pa_2*inv_std_maj_2; } } }