void oskar_sky_copy(oskar_Sky* dst, const oskar_Sky* src, int* status) { int num_sources; /* Check if safe to proceed. */ if (*status) return; if (oskar_sky_precision(dst) != oskar_sky_precision(src)) { *status = OSKAR_ERR_BAD_DATA_TYPE; return; } if (oskar_sky_capacity(dst) < oskar_sky_capacity(src)) { *status = OSKAR_ERR_DIMENSION_MISMATCH; return; } /* Copy meta data */ num_sources = src->num_sources; dst->num_sources = num_sources; dst->use_extended = src->use_extended; dst->reference_ra_rad = src->reference_ra_rad; dst->reference_dec_rad = src->reference_dec_rad; /* Copy the memory blocks */ oskar_mem_copy_contents(dst->ra_rad, src->ra_rad, 0, 0, num_sources, status); oskar_mem_copy_contents(dst->dec_rad, src->dec_rad, 0, 0, num_sources, status); oskar_mem_copy_contents(dst->I, src->I, 0, 0, num_sources, status); oskar_mem_copy_contents(dst->Q, src->Q, 0, 0, num_sources, status); oskar_mem_copy_contents(dst->U, src->U, 0, 0, num_sources, status); oskar_mem_copy_contents(dst->V, src->V, 0, 0, num_sources, status); oskar_mem_copy_contents(dst->reference_freq_hz, src->reference_freq_hz, 0, 0, num_sources, status); oskar_mem_copy_contents(dst->spectral_index, src->spectral_index, 0, 0, num_sources, status); oskar_mem_copy_contents(dst->rm_rad, src->rm_rad, 0, 0, num_sources, status); oskar_mem_copy_contents(dst->l, src->l, 0, 0, num_sources, status); oskar_mem_copy_contents(dst->m, src->m, 0, 0, num_sources, status); oskar_mem_copy_contents(dst->n, src->n, 0, 0, num_sources, status); oskar_mem_copy_contents(dst->fwhm_major_rad, src->fwhm_major_rad, 0, 0, num_sources, status); oskar_mem_copy_contents(dst->fwhm_minor_rad, src->fwhm_minor_rad, 0, 0, num_sources, status); oskar_mem_copy_contents(dst->pa_rad, src->pa_rad, 0, 0, num_sources, status); oskar_mem_copy_contents(dst->gaussian_a, src->gaussian_a, 0, 0, num_sources, status); oskar_mem_copy_contents(dst->gaussian_b, src->gaussian_b, 0, 0, num_sources, status); oskar_mem_copy_contents(dst->gaussian_c, src->gaussian_c, 0, 0, num_sources, status); }
static PyObject* append_file(PyObject* self, PyObject* args) { oskar_Sky *h = 0, *t = 0; PyObject* capsule = 0; int status = 0; const char* filename = 0; if (!PyArg_ParseTuple(args, "Os", &capsule, &filename)) return 0; if (!(h = get_handle(capsule))) return 0; /* Load the sky model. */ t = oskar_sky_load(filename, oskar_sky_precision(h), &status); oskar_sky_append(h, t, &status); oskar_sky_free(t, &status); /* Check for errors. */ if (status) { PyErr_Format(PyExc_RuntimeError, "oskar_sky_load() failed with code %d (%s).", status, oskar_get_error_string(status)); return 0; } return Py_BuildValue(""); }
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; } } }
void oskar_evaluate_jones_Z(oskar_Jones* Z, const oskar_Sky* sky, const oskar_Telescope* telescope, const oskar_SettingsIonosphere* settings, double gast, double frequency_hz, oskar_WorkJonesZ* work, int* status) { int i, num_sources, num_stations; /* Station position in ECEF frame */ double station_x, station_y, station_z, wavelength; oskar_Mem *Z_station; int type; oskar_Sky* sky_cpu; /* Copy of the sky model on the CPU */ /* Check if safe to proceed. */ if (*status) return; /* Check data types. */ type = oskar_sky_precision(sky); if (oskar_telescope_precision(telescope) != type || oskar_jones_type(Z) != (type | OSKAR_COMPLEX) || oskar_work_jones_z_type(work) != type) { *status = OSKAR_ERR_BAD_DATA_TYPE; return; } /* For now, this function requires data is on the CPU .. check this. */ /* Resize the work array (if needed) */ num_stations = oskar_telescope_num_stations(telescope); num_sources = oskar_sky_num_sources(sky); oskar_work_jones_z_resize(work, num_sources, status); /* Copy the sky model to the CPU. */ sky_cpu = oskar_sky_create_copy(sky, OSKAR_CPU, status); Z_station = oskar_mem_create_alias(0, 0, 0, status); wavelength = 299792458.0 / frequency_hz; /* Evaluate the ionospheric phase screen for each station at each * source pierce point. */ for (i = 0; i < num_stations; ++i) { double last, lon, lat; const oskar_Station* station; station = oskar_telescope_station_const(telescope, i); lon = oskar_station_lon_rad(station); lat = oskar_station_lat_rad(station); last = gast + lon; /* Evaluate horizontal x,y,z source positions (for which to evaluate * pierce points) */ oskar_convert_relative_directions_to_enu_directions( work->hor_x, work->hor_y, work->hor_z, num_sources, oskar_sky_l_const(sky_cpu), oskar_sky_m_const(sky_cpu), oskar_sky_n_const(sky_cpu), last - oskar_sky_reference_ra_rad(sky_cpu), oskar_sky_reference_dec_rad(sky_cpu), lat, status); /* Obtain station coordinates in the ECEF frame. */ evaluate_station_ECEF_coords(&station_x, &station_y, &station_z, i, telescope); /* Obtain the pierce points. */ /* FIXME(BM) this is current hard-coded to TID height screen 0 * this fix is only needed to support multiple screen heights. */ oskar_evaluate_pierce_points(work->pp_lon, work->pp_lat, work->pp_rel_path, station_x, station_y, station_z, settings->TID[0].height_km * 1000., num_sources, work->hor_x, work->hor_y, work->hor_z, status); /* Evaluate TEC values for the pierce points */ oskar_evaluate_TEC(work, num_sources, settings, gast, status); /* Get a pointer to the Jones matrices for the station */ oskar_jones_get_station_pointer(Z_station, Z, i, status); /* Populate the Jones matrix with ionospheric phase */ evaluate_jones_Z_station(Z_station, wavelength, work->total_TEC, work->hor_z, settings->min_elevation, num_sources, status); } oskar_sky_free(sky_cpu, status); oskar_mem_free(Z_station, status); }
void oskar_auto_correlate(oskar_Mem* vis, int n_sources, const oskar_Jones* J, const oskar_Sky* sky, int* status) { int jones_type, base_type, location, matrix_type, n_stations; /* Check if safe to proceed. */ if (*status) return; /* Get the data dimensions. */ n_stations = oskar_jones_num_stations(J); /* Check data locations. */ location = oskar_sky_mem_location(sky); if (oskar_jones_mem_location(J) != location || oskar_mem_location(vis) != location) { *status = OSKAR_ERR_LOCATION_MISMATCH; return; } /* Check for consistent data types. */ jones_type = oskar_jones_type(J); base_type = oskar_sky_precision(sky); matrix_type = oskar_type_is_matrix(jones_type) && oskar_mem_is_matrix(vis); if (oskar_mem_precision(vis) != base_type || oskar_type_precision(jones_type) != base_type) { *status = OSKAR_ERR_TYPE_MISMATCH; return; } if (oskar_mem_type(vis) != jones_type) { *status = OSKAR_ERR_TYPE_MISMATCH; return; } /* If neither single or double precision, return error. */ if (base_type != OSKAR_SINGLE && base_type != OSKAR_DOUBLE) { *status = OSKAR_ERR_BAD_DATA_TYPE; return; } /* Check the input dimensions. */ if (oskar_jones_num_sources(J) < n_sources) { *status = OSKAR_ERR_DIMENSION_MISMATCH; return; } /* Select kernel. */ if (base_type == OSKAR_DOUBLE) { const double *I_, *Q_, *U_, *V_; I_ = oskar_mem_double_const(oskar_sky_I_const(sky), status); Q_ = oskar_mem_double_const(oskar_sky_Q_const(sky), status); U_ = oskar_mem_double_const(oskar_sky_U_const(sky), status); V_ = oskar_mem_double_const(oskar_sky_V_const(sky), status); if (matrix_type) { double4c *vis_; const double4c *J_; vis_ = oskar_mem_double4c(vis, status); J_ = oskar_jones_double4c_const(J, status); if (location == OSKAR_GPU) { #ifdef OSKAR_HAVE_CUDA oskar_auto_correlate_cuda_d(n_sources, n_stations, J_, I_, Q_, U_, V_, vis_); oskar_device_check_error(status); #else *status = OSKAR_ERR_CUDA_NOT_AVAILABLE; #endif } else /* CPU */ { oskar_auto_correlate_omp_d(n_sources, n_stations, J_, I_, Q_, U_, V_, vis_); } } else /* Scalar version. */ { double2 *vis_; const double2 *J_; vis_ = oskar_mem_double2(vis, status); J_ = oskar_jones_double2_const(J, status); if (location == OSKAR_GPU) { #ifdef OSKAR_HAVE_CUDA oskar_auto_correlate_scalar_cuda_d(n_sources, n_stations, J_, I_, vis_); oskar_device_check_error(status); #else *status = OSKAR_ERR_CUDA_NOT_AVAILABLE; #endif } else /* CPU */ { oskar_auto_correlate_scalar_omp_d(n_sources, n_stations, J_, I_, vis_); } } } else /* Single precision. */ { const float *I_, *Q_, *U_, *V_; I_ = oskar_mem_float_const(oskar_sky_I_const(sky), status); Q_ = oskar_mem_float_const(oskar_sky_Q_const(sky), status); U_ = oskar_mem_float_const(oskar_sky_U_const(sky), status); V_ = oskar_mem_float_const(oskar_sky_V_const(sky), status); if (matrix_type) { float4c *vis_; const float4c *J_; vis_ = oskar_mem_float4c(vis, status); J_ = oskar_jones_float4c_const(J, status); if (location == OSKAR_GPU) { #ifdef OSKAR_HAVE_CUDA oskar_auto_correlate_cuda_f(n_sources, n_stations, J_, I_, Q_, U_, V_, vis_); oskar_device_check_error(status); #else *status = OSKAR_ERR_CUDA_NOT_AVAILABLE; #endif } else /* CPU */ { oskar_auto_correlate_omp_f(n_sources, n_stations, J_, I_, Q_, U_, V_, vis_); } } else /* Scalar version. */ { float2 *vis_; const float2 *J_; vis_ = oskar_mem_float2(vis, status); J_ = oskar_jones_float2_const(J, status); if (location == OSKAR_GPU) { #ifdef OSKAR_HAVE_CUDA oskar_auto_correlate_scalar_cuda_f(n_sources, n_stations, J_, I_, vis_); oskar_device_check_error(status); #else *status = OSKAR_ERR_CUDA_NOT_AVAILABLE; #endif } else /* CPU */ { oskar_auto_correlate_scalar_omp_f(n_sources, n_stations, J_, I_, vis_); } } } }
static PyObject* append_sources(PyObject* self, PyObject* args) { oskar_Sky *h = 0; PyObject *obj[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; oskar_Mem *ra_c, *dec_c, *I_c, *Q_c, *U_c, *V_c; oskar_Mem *ref_c, *spix_c, *rm_c, *maj_c, *min_c, *pa_c; PyArrayObject *ra = 0, *dec = 0, *I = 0, *Q = 0, *U = 0, *V = 0; PyArrayObject *ref = 0, *spix = 0, *rm = 0, *maj = 0, *min = 0, *pa = 0; int status = 0, npy_type, type, flags, num_sources, old_num; /* Parse inputs: RA, Dec, I, Q, U, V, ref, spix, rm, maj, min, pa. */ if (!PyArg_ParseTuple(args, "OOOOOOOOOOOOO", &obj[0], &obj[1], &obj[2], &obj[3], &obj[4], &obj[5], &obj[6], &obj[7], &obj[8], &obj[9], &obj[10], &obj[11], &obj[12])) return 0; if (!(h = get_handle(obj[0]))) return 0; /* Make sure input objects are arrays. Convert if required. */ flags = NPY_ARRAY_FORCECAST | NPY_ARRAY_IN_ARRAY; type = oskar_sky_precision(h); npy_type = numpy_type_from_oskar(type); ra = (PyArrayObject*) PyArray_FROM_OTF(obj[1], npy_type, flags); dec = (PyArrayObject*) PyArray_FROM_OTF(obj[2], npy_type, flags); I = (PyArrayObject*) PyArray_FROM_OTF(obj[3], npy_type, flags); Q = (PyArrayObject*) PyArray_FROM_OTF(obj[4], npy_type, flags); U = (PyArrayObject*) PyArray_FROM_OTF(obj[5], npy_type, flags); V = (PyArrayObject*) PyArray_FROM_OTF(obj[6], npy_type, flags); ref = (PyArrayObject*) PyArray_FROM_OTF(obj[7], npy_type, flags); spix = (PyArrayObject*) PyArray_FROM_OTF(obj[8], npy_type, flags); rm = (PyArrayObject*) PyArray_FROM_OTF(obj[9], npy_type, flags); maj = (PyArrayObject*) PyArray_FROM_OTF(obj[10], npy_type, flags); min = (PyArrayObject*) PyArray_FROM_OTF(obj[11], npy_type, flags); pa = (PyArrayObject*) PyArray_FROM_OTF(obj[12], npy_type, flags); if (!ra || !dec || !I || !Q || !U || !V || !ref || !spix || !rm || !maj || !min || !pa) goto fail; /* Check size of input arrays. */ num_sources = (int) PyArray_SIZE(I); if (num_sources != (int) PyArray_SIZE(ra) || num_sources != (int) PyArray_SIZE(dec) || num_sources != (int) PyArray_SIZE(Q) || num_sources != (int) PyArray_SIZE(U) || num_sources != (int) PyArray_SIZE(V) || num_sources != (int) PyArray_SIZE(ref) || num_sources != (int) PyArray_SIZE(spix) || num_sources != (int) PyArray_SIZE(rm) || num_sources != (int) PyArray_SIZE(maj) || num_sources != (int) PyArray_SIZE(min) || num_sources != (int) PyArray_SIZE(pa)) { PyErr_SetString(PyExc_RuntimeError, "Input data dimension mismatch."); goto fail; } /* Pointers to input arrays. */ ra_c = oskar_mem_create_alias_from_raw(PyArray_DATA(ra), type, OSKAR_CPU, num_sources, &status); dec_c = oskar_mem_create_alias_from_raw(PyArray_DATA(dec), type, OSKAR_CPU, num_sources, &status); I_c = oskar_mem_create_alias_from_raw(PyArray_DATA(I), type, OSKAR_CPU, num_sources, &status); Q_c = oskar_mem_create_alias_from_raw(PyArray_DATA(Q), type, OSKAR_CPU, num_sources, &status); U_c = oskar_mem_create_alias_from_raw(PyArray_DATA(U), type, OSKAR_CPU, num_sources, &status); V_c = oskar_mem_create_alias_from_raw(PyArray_DATA(V), type, OSKAR_CPU, num_sources, &status); ref_c = oskar_mem_create_alias_from_raw(PyArray_DATA(ref), type, OSKAR_CPU, num_sources, &status); spix_c = oskar_mem_create_alias_from_raw(PyArray_DATA(spix), type, OSKAR_CPU, num_sources, &status); rm_c = oskar_mem_create_alias_from_raw(PyArray_DATA(rm), type, OSKAR_CPU, num_sources, &status); maj_c = oskar_mem_create_alias_from_raw(PyArray_DATA(maj), type, OSKAR_CPU, num_sources, &status); min_c = oskar_mem_create_alias_from_raw(PyArray_DATA(min), type, OSKAR_CPU, num_sources, &status); pa_c = oskar_mem_create_alias_from_raw(PyArray_DATA(pa), type, OSKAR_CPU, num_sources, &status); /* Copy source data into the sky model. */ old_num = oskar_sky_num_sources(h); oskar_sky_resize(h, old_num + num_sources, &status); oskar_mem_copy_contents(oskar_sky_ra_rad(h), ra_c, old_num, 0, num_sources, &status); oskar_mem_copy_contents(oskar_sky_dec_rad(h), dec_c, old_num, 0, num_sources, &status); oskar_mem_copy_contents(oskar_sky_I(h), I_c, old_num, 0, num_sources, &status); oskar_mem_copy_contents(oskar_sky_Q(h), Q_c, old_num, 0, num_sources, &status); oskar_mem_copy_contents(oskar_sky_U(h), U_c, old_num, 0, num_sources, &status); oskar_mem_copy_contents(oskar_sky_V(h), V_c, old_num, 0, num_sources, &status); oskar_mem_copy_contents(oskar_sky_reference_freq_hz(h), ref_c, old_num, 0, num_sources, &status); oskar_mem_copy_contents(oskar_sky_spectral_index(h), spix_c, old_num, 0, num_sources, &status); oskar_mem_copy_contents(oskar_sky_rotation_measure_rad(h), rm_c, old_num, 0, num_sources, &status); oskar_mem_copy_contents(oskar_sky_fwhm_major_rad(h), maj_c, old_num, 0, num_sources, &status); oskar_mem_copy_contents(oskar_sky_fwhm_minor_rad(h), min_c, old_num, 0, num_sources, &status); oskar_mem_copy_contents(oskar_sky_position_angle_rad(h), pa_c, old_num, 0, num_sources, &status); /* Free memory. */ oskar_mem_free(ra_c, &status); oskar_mem_free(dec_c, &status); oskar_mem_free(I_c, &status); oskar_mem_free(Q_c, &status); oskar_mem_free(U_c, &status); oskar_mem_free(V_c, &status); oskar_mem_free(ref_c, &status); oskar_mem_free(spix_c, &status); oskar_mem_free(rm_c, &status); oskar_mem_free(maj_c, &status); oskar_mem_free(min_c, &status); oskar_mem_free(pa_c, &status); /* Check for errors. */ if (status) { PyErr_Format(PyExc_RuntimeError, "Sky model append_sources() failed with code %d (%s).", status, oskar_get_error_string(status)); goto fail; } Py_XDECREF(ra); Py_XDECREF(dec); Py_XDECREF(I); Py_XDECREF(Q); Py_XDECREF(U); Py_XDECREF(V); Py_XDECREF(ref); Py_XDECREF(spix); Py_XDECREF(rm); Py_XDECREF(maj); Py_XDECREF(min); Py_XDECREF(pa); return Py_BuildValue(""); fail: Py_XDECREF(ra); Py_XDECREF(dec); Py_XDECREF(I); Py_XDECREF(Q); Py_XDECREF(U); Py_XDECREF(V); Py_XDECREF(ref); Py_XDECREF(spix); Py_XDECREF(rm); Py_XDECREF(maj); Py_XDECREF(min); Py_XDECREF(pa); return 0; }
/* Wrapper. */ void oskar_sky_scale_flux_with_frequency(oskar_Sky* sky, double frequency, int* status) { int type, location, num_sources; /* Check if safe to proceed. */ if (*status) return; /* Get the type, location and dimensions. */ type = oskar_sky_precision(sky); location = oskar_sky_mem_location(sky); num_sources = oskar_sky_num_sources(sky); /* Scale the flux values. */ if (location == OSKAR_CPU) { if (type == OSKAR_SINGLE) oskar_sky_scale_flux_with_frequency_f(num_sources, frequency, oskar_mem_float(oskar_sky_I(sky), status), oskar_mem_float(oskar_sky_Q(sky), status), oskar_mem_float(oskar_sky_U(sky), status), oskar_mem_float(oskar_sky_V(sky), status), oskar_mem_float(oskar_sky_reference_freq_hz(sky), status), oskar_mem_float_const( oskar_sky_spectral_index_const(sky), status), oskar_mem_float_const( oskar_sky_rotation_measure_rad_const(sky), status)); else if (type == OSKAR_DOUBLE) oskar_sky_scale_flux_with_frequency_d(num_sources, frequency, oskar_mem_double(oskar_sky_I(sky), status), oskar_mem_double(oskar_sky_Q(sky), status), oskar_mem_double(oskar_sky_U(sky), status), oskar_mem_double(oskar_sky_V(sky), status), oskar_mem_double(oskar_sky_reference_freq_hz(sky), status), oskar_mem_double_const( oskar_sky_spectral_index_const(sky), status), oskar_mem_double_const( oskar_sky_rotation_measure_rad_const(sky), status)); else *status = OSKAR_ERR_BAD_DATA_TYPE; } else if (location == OSKAR_GPU) { #ifdef OSKAR_HAVE_CUDA if (type == OSKAR_SINGLE) oskar_sky_scale_flux_with_frequency_cuda_f(num_sources, frequency, oskar_mem_float(oskar_sky_I(sky), status), oskar_mem_float(oskar_sky_Q(sky), status), oskar_mem_float(oskar_sky_U(sky), status), oskar_mem_float(oskar_sky_V(sky), status), oskar_mem_float(oskar_sky_reference_freq_hz(sky), status), oskar_mem_float_const( oskar_sky_spectral_index_const(sky), status), oskar_mem_float_const( oskar_sky_rotation_measure_rad_const(sky), status)); else if (type == OSKAR_DOUBLE) oskar_sky_scale_flux_with_frequency_cuda_d(num_sources, frequency, oskar_mem_double(oskar_sky_I(sky), status), oskar_mem_double(oskar_sky_Q(sky), status), oskar_mem_double(oskar_sky_U(sky), status), oskar_mem_double(oskar_sky_V(sky), status), oskar_mem_double(oskar_sky_reference_freq_hz(sky), status), oskar_mem_double_const( oskar_sky_spectral_index_const(sky), status), oskar_mem_double_const( oskar_sky_rotation_measure_rad_const(sky), status)); else *status = OSKAR_ERR_BAD_DATA_TYPE; oskar_device_check_error(status); #else *status = OSKAR_ERR_CUDA_NOT_AVAILABLE; #endif } else if (location & OSKAR_CL) { #ifdef OSKAR_HAVE_OPENCL cl_event event; cl_kernel k = 0; cl_int error, num; cl_uint arg = 0; size_t global_size, local_size; if (type == OSKAR_DOUBLE) k = oskar_cl_kernel("scale_flux_with_frequency_double"); else if (type == OSKAR_SINGLE) k = oskar_cl_kernel("scale_flux_with_frequency_float"); else { *status = OSKAR_ERR_BAD_DATA_TYPE; return; } if (!k) { *status = OSKAR_ERR_FUNCTION_NOT_AVAILABLE; return; } /* Set kernel arguments. */ num = (cl_int) num_sources; error = clSetKernelArg(k, arg++, sizeof(cl_int), &num); if (type == OSKAR_SINGLE) { const cl_float freq = (cl_float) frequency; error |= clSetKernelArg(k, arg++, sizeof(cl_float), &freq); } else if (type == OSKAR_DOUBLE) { const cl_double freq = (cl_double) frequency; error |= clSetKernelArg(k, arg++, sizeof(cl_double), &freq); } error |= clSetKernelArg(k, arg++, sizeof(cl_mem), oskar_mem_cl_buffer(oskar_sky_I(sky), status)); error |= clSetKernelArg(k, arg++, sizeof(cl_mem), oskar_mem_cl_buffer(oskar_sky_Q(sky), status)); error |= clSetKernelArg(k, arg++, sizeof(cl_mem), oskar_mem_cl_buffer(oskar_sky_U(sky), status)); error |= clSetKernelArg(k, arg++, sizeof(cl_mem), oskar_mem_cl_buffer(oskar_sky_V(sky), status)); error |= clSetKernelArg(k, arg++, sizeof(cl_mem), oskar_mem_cl_buffer(oskar_sky_reference_freq_hz(sky), status)); error |= clSetKernelArg(k, arg++, sizeof(cl_mem), oskar_mem_cl_buffer_const(oskar_sky_spectral_index_const(sky), status)); error |= clSetKernelArg(k, arg++, sizeof(cl_mem), oskar_mem_cl_buffer_const(oskar_sky_rotation_measure_rad_const(sky), status)); if (error != CL_SUCCESS) { *status = OSKAR_ERR_INVALID_ARGUMENT; return; } /* Launch kernel on current command queue. */ local_size = oskar_cl_is_gpu() ? 256 : 128; global_size = ((num + local_size - 1) / local_size) * local_size; error = clEnqueueNDRangeKernel(oskar_cl_command_queue(), k, 1, NULL, &global_size, &local_size, 0, NULL, &event); if (error != CL_SUCCESS) *status = OSKAR_ERR_KERNEL_LAUNCH_FAILURE; #else *status = OSKAR_ERR_OPENCL_NOT_AVAILABLE; #endif } else *status = OSKAR_ERR_BAD_LOCATION; }
void oskar_sky_append_to_set(int* set_size, oskar_Sky*** set_ptr, int max_sources_per_model, const oskar_Sky* model, int* status) { int free_space, space_required, num_extra_models, number_to_copy; int i, j, type, location, from_offset; oskar_Sky **set; size_t new_size; /* Check if safe to proceed. */ if (*status) return; /* Get type and location. */ type = oskar_sky_precision(model); location = oskar_sky_mem_location(model); if (location != OSKAR_CPU) { *status = OSKAR_ERR_BAD_LOCATION; return; } /* Work out if the set needs to be resized, and if so by how much. */ free_space = (*set_size == 0) ? 0 : max_sources_per_model - (*set_ptr)[*set_size - 1]->num_sources; space_required = model->num_sources - free_space; num_extra_models = (space_required + max_sources_per_model - 1) / max_sources_per_model; /* Sanity check. */ if (num_extra_models < 0) { *status = OSKAR_ERR_INVALID_ARGUMENT; return; } /* Resize the array of sky model handles. */ new_size = (*set_size + num_extra_models) * sizeof(oskar_Sky*); *set_ptr = realloc((*set_ptr), new_size); set = *set_ptr; for (i = *set_size; i < *set_size + num_extra_models; ++i) { set[i] = oskar_sky_create(type, location, max_sources_per_model, status); /* TODO Please clarify this statement and explain why it's needed. */ /* Set the number sources to zero as this is the number currently * allocated in the model. */ set[i]->num_sources = 0; } if (*status) return; /* Copy sources from the model into the set. */ /* Loop over set entries with free space and copy sources into them. */ number_to_copy = model->num_sources; from_offset = 0; for (i = (*set_size-1 > 0) ? *set_size-1 : 0; i < *set_size + num_extra_models; ++i) { int n_copy, offset_dst; offset_dst = oskar_sky_num_sources(set[i]); free_space = max_sources_per_model - offset_dst; n_copy = MIN(free_space, number_to_copy); oskar_sky_copy_contents(set[i], model, offset_dst, from_offset, n_copy, status); if (*status) break; set[i]->num_sources = n_copy + offset_dst; number_to_copy -= n_copy; from_offset += n_copy; } if (*status) return; /* Set the use extended flag if needed. */ for (j = (*set_size-1 > 0) ? *set_size-1 : 0; j < *set_size + num_extra_models; ++j) { oskar_Sky* sky = set[j]; const oskar_Mem *major, *minor; /* If any source in the model is extended, set the flag. */ major = oskar_sky_fwhm_major_rad_const(sky); minor = oskar_sky_fwhm_minor_rad_const(sky); if (type == OSKAR_DOUBLE) { const double *maj_, *min_; maj_ = oskar_mem_double_const(major, status); min_ = oskar_mem_double_const(minor, status); for (i = 0; i < sky->num_sources; ++i) { if (maj_[i] > 0.0 || min_[i] > 0.0) { sky->use_extended = OSKAR_TRUE; break; } } } else { const float *maj_, *min_; maj_ = oskar_mem_float_const(major, status); min_ = oskar_mem_float_const(minor, status); for (i = 0; i < sky->num_sources; ++i) { if (maj_[i] > 0.0 || min_[i] > 0.0) { sky->use_extended = OSKAR_TRUE; break; } } } } /* Update the set size */ *set_size += num_extra_models; }