oskar_Sky* oskar_sky_generate_grid(int precision, double ra0_rad, double dec0_rad, int side_length, double fov_rad, double mean_flux_jy, double std_flux_jy, int seed, int* status) { oskar_Sky* t = 0; int i, j, k, num_points; double r[2]; /* Check if safe to proceed. */ if (*status) return 0; /* Create a temporary sky model. */ num_points = side_length * side_length; t = oskar_sky_create(precision, OSKAR_CPU, num_points, status); /* Side length of 1 is a special case. */ if (side_length == 1) { /* Generate the Stokes I flux and store the value. */ oskar_random_gaussian2(seed, 0, 0, r); r[0] = mean_flux_jy + std_flux_jy * r[0]; oskar_sky_set_source(t, 0, ra0_rad, dec0_rad, r[0], 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, status); } else { double l_max, l, m, n, sin_dec0, cos_dec0, ra, dec; l_max = sin(0.5 * fov_rad); sin_dec0 = sin(dec0_rad); cos_dec0 = cos(dec0_rad); for (j = 0, k = 0; j < side_length; ++j) { m = 2.0 * l_max * j / (side_length - 1) - l_max; for (i = 0; i < side_length; ++i, ++k) { l = -2.0 * l_max * i / (side_length - 1) + l_max; /* Get longitude and latitude from tangent plane coords. */ n = sqrt(1.0 - l*l - m*m); dec = asin(n * sin_dec0 + m * cos_dec0); ra = ra0_rad + atan2(l, cos_dec0 * n - m * sin_dec0); /* Generate the Stokes I flux and store the value. */ oskar_random_gaussian2(seed, i, j, r); r[0] = mean_flux_jy + std_flux_jy * r[0]; oskar_sky_set_source(t, k, ra, dec, r[0], 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, status); } } } return t; }
static PyObject* create(PyObject* self, PyObject* args) { oskar_Sky* h = 0; PyObject* capsule = 0; int status = 0, prec = 0; const char* type; if (!PyArg_ParseTuple(args, "s", &type)) return 0; prec = (type[0] == 'S' || type[0] == 's') ? OSKAR_SINGLE : OSKAR_DOUBLE; h = oskar_sky_create(prec, OSKAR_CPU, 0, &status); capsule = PyCapsule_New((void*)h, name, (PyCapsule_Destructor)sky_free); return Py_BuildValue("N", capsule); /* Don't increment refcount. */ }
int benchmark(int num_stations, int num_sources, int type, int jones_type, int loc, int use_extended, int use_time_ave, int niter, std::vector<double>& times) { int status = 0; oskar_Timer* timer; timer = oskar_timer_create(loc == OSKAR_GPU ? OSKAR_TIMER_CUDA : OSKAR_TIMER_OMP); // Set up a test sky model, telescope model and Jones matrices. oskar_Telescope* tel = oskar_telescope_create(type, loc, num_stations, &status); oskar_Sky* sky = oskar_sky_create(type, loc, num_sources, &status); oskar_Jones* J = oskar_jones_create(jones_type, loc, num_stations, num_sources, &status); oskar_telescope_set_channel_bandwidth(tel, 1e6); oskar_telescope_set_time_average(tel, (double) use_time_ave); oskar_sky_set_use_extended(sky, use_extended); // Memory for visibility coordinates and output visibility slice. oskar_Mem *vis, *u, *v, *w; vis = oskar_mem_create(jones_type, loc, oskar_telescope_num_baselines(tel), &status); u = oskar_mem_create(type, loc, num_stations, &status); v = oskar_mem_create(type, loc, num_stations, &status); w = oskar_mem_create(type, loc, num_stations, &status); // Run benchmark. times.resize(niter); for (int i = 0; i < niter; ++i) { oskar_timer_start(timer); oskar_cross_correlate(vis, oskar_sky_num_sources(sky), J, sky, tel, u, v, w, 0.0, 100e6, &status); times[i] = oskar_timer_elapsed(timer); } // Free memory. oskar_mem_free(u, &status); oskar_mem_free(v, &status); oskar_mem_free(w, &status); oskar_mem_free(vis, &status); oskar_jones_free(J, &status); oskar_telescope_free(tel, &status); oskar_sky_free(sky, &status); oskar_timer_free(timer); return status; }
void createTestData(int precision, int location, int matrix) { int status = 0, type; // Allocate memory for data structures. type = precision | OSKAR_COMPLEX; if (matrix) type |= OSKAR_MATRIX; jones = oskar_jones_create(type, location, num_stations, num_sources, &status); u_ = oskar_mem_create(precision, location, num_stations, &status); v_ = oskar_mem_create(precision, location, num_stations, &status); w_ = oskar_mem_create(precision, location, num_stations, &status); sky = oskar_sky_create(precision, location, num_sources, &status); tel = oskar_telescope_create(precision, location, num_stations, &status); ASSERT_EQ(0, status) << oskar_get_error_string(status); // Fill data structures with random data in sensible ranges. srand(2); oskar_mem_random_range(oskar_jones_mem(jones), 1.0, 5.0, &status); oskar_mem_random_range(u_, 1.0, 5.0, &status); oskar_mem_random_range(v_, 1.0, 5.0, &status); oskar_mem_random_range(w_, 1.0, 5.0, &status); oskar_mem_random_range( oskar_telescope_station_true_x_offset_ecef_metres(tel), 0.1, 1000.0, &status); oskar_mem_random_range( oskar_telescope_station_true_y_offset_ecef_metres(tel), 0.1, 1000.0, &status); oskar_mem_random_range( oskar_telescope_station_true_z_offset_ecef_metres(tel), 0.1, 1000.0, &status); oskar_mem_random_range(oskar_sky_I(sky), 1.0, 2.0, &status); oskar_mem_random_range(oskar_sky_Q(sky), 0.1, 1.0, &status); oskar_mem_random_range(oskar_sky_U(sky), 0.1, 0.5, &status); oskar_mem_random_range(oskar_sky_V(sky), 0.1, 0.2, &status); oskar_mem_random_range(oskar_sky_l(sky), 0.1, 0.9, &status); oskar_mem_random_range(oskar_sky_m(sky), 0.1, 0.9, &status); oskar_mem_random_range(oskar_sky_n(sky), 0.1, 0.9, &status); oskar_mem_random_range(oskar_sky_gaussian_a(sky), 0.1e-6, 0.2e-6, &status); oskar_mem_random_range(oskar_sky_gaussian_b(sky), 0.1e-6, 0.2e-6, &status); oskar_mem_random_range(oskar_sky_gaussian_c(sky), 0.1e-6, 0.2e-6, &status); ASSERT_EQ(0, status) << oskar_get_error_string(status); }
oskar_Sky* oskar_sky_load(const char* filename, int type, int* status) { int n = 0; FILE* file; char* line = 0; size_t bufsize = 0; oskar_Sky* sky; /* Check if safe to proceed. */ if (*status) return 0; /* Get the data type. */ if (type != OSKAR_SINGLE && type != OSKAR_DOUBLE) { *status = OSKAR_ERR_BAD_DATA_TYPE; return 0; } /* Open the file. */ file = fopen(filename, "r"); if (!file) { *status = OSKAR_ERR_FILE_IO; return 0; } /* Initialise the sky model. */ sky = oskar_sky_create(type, OSKAR_CPU, 0, status); /* Loop over lines in file. */ while (oskar_getline(&line, &bufsize, file) != OSKAR_ERR_EOF) { /* Set defaults. */ /* RA, Dec, I, Q, U, V, freq0, spix, RM, FWHM maj, FWHM min, PA */ double par[] = {0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.}; size_t num_param = sizeof(par) / sizeof(double); size_t num_required = 3, num_read = 0; /* Load source parameters (require at least RA, Dec, Stokes I). */ num_read = oskar_string_to_array_d(line, num_param, par); if (num_read < num_required) continue; /* Ensure enough space in arrays. */ if (oskar_sky_num_sources(sky) <= n) { oskar_sky_resize(sky, n + 100, status); if (*status) break; } if (num_read <= 9) { /* RA, Dec, I, Q, U, V, freq0, spix, RM */ oskar_sky_set_source(sky, n, par[0] * deg2rad, par[1] * deg2rad, par[2], par[3], par[4], par[5], par[6], par[7], par[8], 0.0, 0.0, 0.0, status); } else if (num_read == 11) { /* Old format, with no rotation measure. */ /* RA, Dec, I, Q, U, V, freq0, spix, FWHM maj, FWHM min, PA */ oskar_sky_set_source(sky, n, par[0] * deg2rad, par[1] * deg2rad, par[2], par[3], par[4], par[5], par[6], par[7], 0.0, par[8] * arcsec2rad, par[9] * arcsec2rad, par[10] * deg2rad, status); } else if (num_read == 12) { /* New format. */ /* RA, Dec, I, Q, U, V, freq0, spix, RM, FWHM maj, FWHM min, PA */ oskar_sky_set_source(sky, n, par[0] * deg2rad, par[1] * deg2rad, par[2], par[3], par[4], par[5], par[6], par[7], par[8], par[9] * arcsec2rad, par[10] * arcsec2rad, par[11] * deg2rad, status); } else { /* Error. */ *status = OSKAR_ERR_BAD_SKY_FILE; break; } ++n; } /* Set the size to be the actual number of elements loaded. */ oskar_sky_resize(sky, n, status); /* Free the line buffer and close the file. */ if (line) free(line); fclose(file); /* Check if an error occurred. */ if (*status) { oskar_sky_free(sky, status); sky = 0; } /* Return a handle to the sky model. */ return sky; }
oskar_Sky* oskar_sky_from_image(int precision, const oskar_Mem* image, int image_width, int image_height, double image_ra_deg, double image_dec_deg, double image_cellsize_deg, double image_freq_hz, double spectral_index, int* status) { int i, type, x, y; double crval[2], crpix[2], cdelt[2], val; oskar_Sky* sky; /* Check if safe to proceed. */ if (*status) return 0; /* Check the image size is even. */ if ((image_width % 2) || (image_height % 2)) { *status = OSKAR_ERR_INVALID_ARGUMENT; return 0; } /* Get reference pixels and reference values in radians. */ crpix[0] = image_width / 2 + 1; crpix[1] = image_height / 2 + 1; crval[0] = image_ra_deg * M_PI / 180.0; crval[1] = image_dec_deg * M_PI / 180.0; /* Compute sine of pixel deltas for inverse orthographic projection. */ cdelt[0] = -sin(image_cellsize_deg * M_PI / 180.0); cdelt[1] = -cdelt[0]; /* Create a sky model. */ sky = oskar_sky_create(precision, OSKAR_CPU, 0, status); /* Store the image pixels. */ type = oskar_mem_precision(image); if (type == OSKAR_SINGLE) { const float *img = oskar_mem_float_const(image, status); for (y = 0, i = 0; y < image_height; ++y) { for (x = 0; x < image_width; ++x) { /* Check pixel value. */ val = (double) (img[image_width * y + x]); if (val == 0.0) continue; set_pixel(sky, i++, x, y, val, crval, crpix, cdelt, image_freq_hz, spectral_index, status); } } } else { const double *img = oskar_mem_double_const(image, status); for (y = 0, i = 0; y < image_height; ++y) { for (x = 0; x < image_width; ++x) { /* Check pixel value. */ val = img[image_width * y + x]; if (val == 0.0) continue; set_pixel(sky, i++, x, y, val, crval, crpix, cdelt, image_freq_hz, spectral_index, status); } } } /* Return the sky model. */ oskar_sky_resize(sky, i, status); return sky; }
static void set_up_device_data(oskar_Simulator* h, int* status) { int i, dev_loc, complx, vistype, num_stations, num_src; if (*status) return; /* Get local variables. */ num_stations = oskar_telescope_num_stations(h->tel); num_src = h->max_sources_per_chunk; complx = (h->prec) | OSKAR_COMPLEX; vistype = complx; if (oskar_telescope_pol_mode(h->tel) == OSKAR_POL_MODE_FULL) vistype |= OSKAR_MATRIX; /* Expand the number of devices to the number of selected GPUs, * if required. */ if (h->num_devices < h->num_gpus) oskar_simulator_set_num_devices(h, h->num_gpus); for (i = 0; i < h->num_devices; ++i) { DeviceData* d = &h->d[i]; d->previous_chunk_index = -1; /* Select the device. */ if (i < h->num_gpus) { oskar_device_set(h->gpu_ids[i], status); dev_loc = OSKAR_GPU; } else { dev_loc = OSKAR_CPU; } /* Timers. */ if (!d->tmr_compute) { d->tmr_compute = oskar_timer_create(OSKAR_TIMER_NATIVE); d->tmr_copy = oskar_timer_create(OSKAR_TIMER_NATIVE); d->tmr_clip = oskar_timer_create(OSKAR_TIMER_NATIVE); d->tmr_E = oskar_timer_create(OSKAR_TIMER_NATIVE); d->tmr_K = oskar_timer_create(OSKAR_TIMER_NATIVE); d->tmr_join = oskar_timer_create(OSKAR_TIMER_NATIVE); d->tmr_correlate = oskar_timer_create(OSKAR_TIMER_NATIVE); } /* Visibility blocks. */ if (!d->vis_block) { d->vis_block = oskar_vis_block_create_from_header(dev_loc, h->header, status); d->vis_block_cpu[0] = oskar_vis_block_create_from_header(OSKAR_CPU, h->header, status); d->vis_block_cpu[1] = oskar_vis_block_create_from_header(OSKAR_CPU, h->header, status); } oskar_vis_block_clear(d->vis_block, status); oskar_vis_block_clear(d->vis_block_cpu[0], status); oskar_vis_block_clear(d->vis_block_cpu[1], status); /* Device scratch memory. */ if (!d->tel) { d->u = oskar_mem_create(h->prec, dev_loc, num_stations, status); d->v = oskar_mem_create(h->prec, dev_loc, num_stations, status); d->w = oskar_mem_create(h->prec, dev_loc, num_stations, status); d->chunk = oskar_sky_create(h->prec, dev_loc, num_src, status); d->chunk_clip = oskar_sky_create(h->prec, dev_loc, num_src, status); d->tel = oskar_telescope_create_copy(h->tel, dev_loc, status); d->J = oskar_jones_create(vistype, dev_loc, num_stations, num_src, status); d->R = oskar_type_is_matrix(vistype) ? oskar_jones_create(vistype, dev_loc, num_stations, num_src, status) : 0; d->E = oskar_jones_create(vistype, dev_loc, num_stations, num_src, status); d->K = oskar_jones_create(complx, dev_loc, num_stations, num_src, status); d->Z = 0; d->station_work = oskar_station_work_create(h->prec, dev_loc, status); } } }
oskar_Sky* oskar_sky_read(const char* filename, int location, int* status) { int type = 0, num_sources = 0, idx = 0; oskar_Binary* h = 0; unsigned char group = OSKAR_TAG_GROUP_SKY_MODEL; oskar_Sky* sky = 0; /* Check if safe to proceed. */ if (*status) return 0; /* Create the handle. */ h = oskar_binary_create(filename, 'r', status); /* Read the sky model data parameters. */ oskar_binary_read_int(h, group, OSKAR_SKY_TAG_NUM_SOURCES, idx, &num_sources, status); oskar_binary_read_int(h, group, OSKAR_SKY_TAG_DATA_TYPE, idx, &type, status); /* Check if safe to proceed. * Status flag will be set if binary read failed. */ if (*status) { oskar_binary_free(h); return 0; } /* Create the sky model structure. */ sky = oskar_sky_create(type, location, num_sources, status); /* Read the arrays. */ oskar_binary_read_mem(h, oskar_sky_ra_rad(sky), group, OSKAR_SKY_TAG_RA, idx, status); oskar_binary_read_mem(h, oskar_sky_dec_rad(sky), group, OSKAR_SKY_TAG_DEC, idx, status); oskar_binary_read_mem(h, oskar_sky_I(sky), group, OSKAR_SKY_TAG_STOKES_I, idx, status); oskar_binary_read_mem(h, oskar_sky_Q(sky), group, OSKAR_SKY_TAG_STOKES_Q, idx, status); oskar_binary_read_mem(h, oskar_sky_U(sky), group, OSKAR_SKY_TAG_STOKES_U, idx, status); oskar_binary_read_mem(h, oskar_sky_V(sky), group, OSKAR_SKY_TAG_STOKES_V, idx, status); oskar_binary_read_mem(h, oskar_sky_reference_freq_hz(sky), group, OSKAR_SKY_TAG_REF_FREQ, idx, status); oskar_binary_read_mem(h, oskar_sky_spectral_index(sky), group, OSKAR_SKY_TAG_SPECTRAL_INDEX, idx, status); oskar_binary_read_mem(h, oskar_sky_fwhm_major_rad(sky), group, OSKAR_SKY_TAG_FWHM_MAJOR, idx, status); oskar_binary_read_mem(h, oskar_sky_fwhm_minor_rad(sky), group, OSKAR_SKY_TAG_FWHM_MINOR, idx, status); oskar_binary_read_mem(h, oskar_sky_position_angle_rad(sky), group, OSKAR_SKY_TAG_POSITION_ANGLE, idx, status); oskar_binary_read_mem(h, oskar_sky_rotation_measure_rad(sky), group, OSKAR_SKY_TAG_ROTATION_MEASURE, idx, status); /* Release the handle. */ oskar_binary_free(h); /* Return a handle to the sky model, or NULL if an error occurred. */ if (*status) { oskar_sky_free(sky, status); sky = 0; } return sky; }
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; }