TEST(binary_file, binary_read_write_mem) { const char filename[] = "temp_test_mem_binary.dat"; int num_cpu = 1000; int num_gpu = 2048; int status = 0; // Create the handle. oskar_Binary* h = oskar_binary_create(filename, 'w', &status); // Save data from CPU. { oskar_Mem* mem = oskar_mem_create(OSKAR_SINGLE, OSKAR_CPU, num_cpu, &status); ASSERT_EQ(0, status) << oskar_get_error_string(status); float* data = oskar_mem_float(mem, &status); // Fill array with data. for (int i = 0; i < num_cpu; ++i) { data[i] = i * 1024.0; } // Save CPU data. oskar_binary_write_mem_ext(h, mem, "USER", "TEST", 987654, 0, &status); ASSERT_EQ(0, status) << oskar_get_error_string(status); oskar_mem_free(mem, &status); } // Save data from GPU. { oskar_Mem *mem_cpu, *mem_gpu; mem_cpu = oskar_mem_create(OSKAR_DOUBLE_COMPLEX, OSKAR_CPU, num_gpu, &status); ASSERT_EQ(0, status) << oskar_get_error_string(status); double2* data = oskar_mem_double2(mem_cpu, &status); // Fill array with data. for (int i = 0; i < num_gpu; ++i) { data[i].x = i * 10.0; data[i].y = i * 20.0 + 1.0; } // Copy data to GPU. mem_gpu = oskar_mem_create_copy(mem_cpu, OSKAR_GPU, &status); ASSERT_EQ(0, status) << oskar_get_error_string(status); // Save GPU data. oskar_binary_write_mem_ext(h, mem_gpu, "AA", "BB", 2, 0, &status); ASSERT_EQ(0, status) << oskar_get_error_string(status); oskar_mem_free(mem_cpu, &status); oskar_mem_free(mem_gpu, &status); } // Save a single integer with a large index. int val = 0xFFFFFF; oskar_binary_write_int(h, 50, 9, 800000, val, &status); ASSERT_EQ(0, status) << oskar_get_error_string(status); // Save data from CPU with blank tags. { oskar_Mem* mem = oskar_mem_create(OSKAR_DOUBLE, OSKAR_CPU, num_cpu, &status); ASSERT_EQ(0, status) << oskar_get_error_string(status); double* data = oskar_mem_double(mem, &status); // Fill array with data. for (int i = 0; i < num_cpu; ++i) { data[i] = i * 500.0; } // Save CPU data. oskar_binary_write_mem_ext(h, mem, "", "", 10, 0, &status); ASSERT_EQ(0, status) << oskar_get_error_string(status); // Fill array with data. for (int i = 0; i < num_cpu; ++i) { data[i] = i * 501.0; } // Save CPU data. oskar_binary_write_mem_ext(h, mem, "", "", 11, 0, &status); ASSERT_EQ(0, status) << oskar_get_error_string(status); oskar_mem_free(mem, &status); } // Save CPU data with tags that are equal lengths. { oskar_Mem* mem = oskar_mem_create(OSKAR_DOUBLE, OSKAR_CPU, num_cpu, &status); ASSERT_EQ(0, status) << oskar_get_error_string(status); double* data = oskar_mem_double(mem, &status); // Fill array with data. for (int i = 0; i < num_cpu; ++i) { data[i] = i * 1001.0; } // Save CPU data. oskar_binary_write_mem_ext(h, mem, "DOG", "CAT", 0, 0, &status); ASSERT_EQ(0, status) << oskar_get_error_string(status); // Fill array with data. for (int i = 0; i < num_cpu; ++i) { data[i] = i * 127.0; } // Save CPU data. oskar_binary_write_mem_ext(h, mem, "ONE", "TWO", 0, 0, &status); ASSERT_EQ(0, status) << oskar_get_error_string(status); oskar_mem_free(mem, &status); } // Create the handle for reading. oskar_binary_free(h); h = oskar_binary_create(filename, 'r', &status); // Load data directly to GPU. { oskar_Mem *mem_gpu, *mem_cpu; mem_gpu = oskar_mem_create(OSKAR_DOUBLE_COMPLEX, OSKAR_GPU, 0, &status); ASSERT_EQ(0, status) << oskar_get_error_string(status); oskar_binary_read_mem_ext(h, mem_gpu, "AA", "BB", 2, &status); ASSERT_EQ(0, status) << oskar_get_error_string(status); EXPECT_EQ(num_gpu, (int)oskar_mem_length(mem_gpu)); // Copy back to CPU and examine contents. mem_cpu = oskar_mem_create_copy(mem_gpu, OSKAR_CPU, &status); ASSERT_EQ(0, status) << oskar_get_error_string(status); double2* data = oskar_mem_double2(mem_cpu, &status); for (int i = 0; i < num_gpu; ++i) { EXPECT_DOUBLE_EQ(i * 10.0, data[i].x); EXPECT_DOUBLE_EQ(i * 20.0 + 1.0, data[i].y); } oskar_mem_free(mem_cpu, &status); oskar_mem_free(mem_gpu, &status); } // Load integer with a large index. int new_val = 0; oskar_binary_read_int(h, 50, 9, 800000, &new_val, &status); ASSERT_EQ(0, status) << oskar_get_error_string(status); EXPECT_EQ(val, new_val); // Load CPU data. { oskar_Mem* mem = oskar_mem_create(OSKAR_SINGLE, OSKAR_CPU, num_cpu, &status); oskar_binary_read_mem_ext(h, mem, "USER", "TEST", 987654, &status); ASSERT_EQ(0, status) << oskar_get_error_string(status); ASSERT_EQ(num_cpu, (int)oskar_mem_length(mem)); float* data = oskar_mem_float(mem, &status); for (int i = 0; i < num_cpu; ++i) { EXPECT_DOUBLE_EQ(i * 1024.0, data[i]); } oskar_mem_free(mem, &status); } // Load CPU data with blank tags. { double* data; oskar_Mem* mem = oskar_mem_create(OSKAR_DOUBLE, OSKAR_CPU, num_cpu, &status); ASSERT_EQ(0, status) << oskar_get_error_string(status); oskar_binary_read_mem_ext(h, mem, "", "", 10, &status); ASSERT_EQ(0, status) << oskar_get_error_string(status); oskar_binary_read_mem_ext(h, mem, "DOESN'T", "EXIST", 10, &status); EXPECT_EQ((int)OSKAR_ERR_BINARY_TAG_NOT_FOUND, status); status = 0; ASSERT_EQ(num_cpu, (int)oskar_mem_length(mem)); data = oskar_mem_double(mem, &status); for (int i = 0; i < num_cpu; ++i) { EXPECT_DOUBLE_EQ(i * 500.0, data[i]); } oskar_binary_read_mem_ext(h, mem, "", "", 11, &status); ASSERT_EQ(0, status) << oskar_get_error_string(status); ASSERT_EQ(num_cpu, (int)oskar_mem_length(mem)); data = oskar_mem_double(mem, &status); for (int i = 0; i < num_cpu; ++i) { EXPECT_DOUBLE_EQ(i * 501.0, data[i]); } oskar_mem_free(mem, &status); } // Load CPU data with tags that are equal lengths. { double* data; oskar_Mem* mem = oskar_mem_create(OSKAR_DOUBLE, OSKAR_CPU, 0, &status); ASSERT_EQ(0, status) << oskar_get_error_string(status); oskar_binary_read_mem_ext(h, mem, "ONE", "TWO", 0, &status); ASSERT_EQ(0, status) << oskar_get_error_string(status); ASSERT_EQ(num_cpu, (int)oskar_mem_length(mem)); data = oskar_mem_double(mem, &status); for (int i = 0; i < num_cpu; ++i) { EXPECT_DOUBLE_EQ(i * 127.0, data[i]); } oskar_binary_read_mem_ext(h, mem, "DOG", "CAT", 0, &status); ASSERT_EQ(0, status) << oskar_get_error_string(status); ASSERT_EQ(num_cpu, (int)oskar_mem_length(mem)); data = oskar_mem_double(mem, &status); for (int i = 0; i < num_cpu; ++i) { EXPECT_DOUBLE_EQ(i * 1001.0, data[i]); } oskar_mem_free(mem, &status); } // Try to load data that isn't present. { oskar_Mem* mem = oskar_mem_create(OSKAR_DOUBLE, OSKAR_CPU, 0, &status); ASSERT_EQ(0, status) << oskar_get_error_string(status); oskar_binary_read_mem_ext(h, mem, "DOESN'T", "EXIST", 10, &status); EXPECT_EQ((int)OSKAR_ERR_BINARY_TAG_NOT_FOUND, status); status = 0; EXPECT_EQ(0, (int)oskar_mem_length(mem)); oskar_mem_free(mem, &status); } // Release the handle. oskar_binary_free(h); ASSERT_EQ(0, status) << oskar_get_error_string(status); }
int main(int argc, char** argv) { int status = 0; oskar::OptionParser opt("oskar_evaulate_pierce_points", oskar_version_string()); opt.add_required("settings file"); if (!opt.check_options(argc, argv)) return EXIT_FAILURE; const char* settings_file = opt.get_arg(); // Create the log. oskar_Log* log = oskar_log_create(OSKAR_LOG_MESSAGE, OSKAR_LOG_STATUS); oskar_log_message(log, 'M', 0, "Running binary %s", argv[0]); // Enum values used in writing time-freq data binary files enum OSKAR_TIME_FREQ_TAGS { TIME_IDX = 0, FREQ_IDX = 1, TIME_MJD_UTC = 2, FREQ_HZ = 3, NUM_FIELDS = 4, NUM_FIELD_TAGS = 5, HEADER_OFFSET = 10, DATA = 0, DIMS = 1, LABEL = 2, UNITS = 3, GRP = OSKAR_TAG_GROUP_TIME_FREQ_DATA }; oskar_Settings_old settings; oskar_settings_old_load(&settings, log, settings_file, &status); oskar_log_set_keep_file(log, settings.sim.keep_log_file); if (status) return status; oskar_Telescope* tel = oskar_settings_to_telescope(&settings, log, &status); oskar_Sky* sky = oskar_settings_to_sky(&settings, log, &status); // FIXME remove this restriction ... (see evaluate Z) if (settings.ionosphere.num_TID_screens != 1) return OSKAR_ERR_SETUP_FAIL; int type = settings.sim.double_precision ? OSKAR_DOUBLE : OSKAR_SINGLE; int loc = OSKAR_CPU; int num_sources = oskar_sky_num_sources(sky); oskar_Mem *hor_x, *hor_y, *hor_z; hor_x = oskar_mem_create(type, loc, num_sources, &status); hor_y = oskar_mem_create(type, loc, num_sources, &status); hor_z = oskar_mem_create(type, loc, num_sources, &status); oskar_Mem *pp_lon, *pp_lat, *pp_rel_path; int num_stations = oskar_telescope_num_stations(tel); int num_pp = num_stations * num_sources; pp_lon = oskar_mem_create(type, loc, num_pp, &status); pp_lat = oskar_mem_create(type, loc, num_pp, &status); pp_rel_path = oskar_mem_create(type, loc, num_pp, &status); // Pierce points for one station (non-owned oskar_Mem pointers) oskar_Mem *pp_st_lon, *pp_st_lat, *pp_st_rel_path; pp_st_lon = oskar_mem_create_alias(0, 0, 0, &status); pp_st_lat = oskar_mem_create_alias(0, 0, 0, &status); pp_st_rel_path = oskar_mem_create_alias(0, 0, 0, &status); int num_times = settings.obs.num_time_steps; double obs_start_mjd_utc = settings.obs.start_mjd_utc; double dt_dump = settings.obs.dt_dump_days; // Binary file meta-data std::string label1 = "pp_lon"; std::string label2 = "pp_lat"; std::string label3 = "pp_path"; std::string units = "radians"; std::string units2 = ""; oskar_Mem *dims = oskar_mem_create(OSKAR_INT, loc, 2, &status); /* FIXME is this the correct dimension order ? * FIXME get the MATLAB reader to respect dimension ordering */ oskar_mem_int(dims, &status)[0] = num_sources; oskar_mem_int(dims, &status)[1] = num_stations; const char* filename = settings.ionosphere.pierce_points.filename; oskar_Binary* h = oskar_binary_create(filename, 'w', &status); double screen_height_m = settings.ionosphere.TID->height_km * 1000.0; // printf("Number of times = %i\n", num_times); // printf("Number of stations = %i\n", num_stations); void *x_, *y_, *z_; x_ = oskar_mem_void(oskar_telescope_station_true_x_offset_ecef_metres(tel)); y_ = oskar_mem_void(oskar_telescope_station_true_y_offset_ecef_metres(tel)); z_ = oskar_mem_void(oskar_telescope_station_true_z_offset_ecef_metres(tel)); for (int t = 0; t < num_times; ++t) { double t_dump = obs_start_mjd_utc + t * dt_dump; // MJD UTC double gast = oskar_convert_mjd_to_gast_fast(t_dump + dt_dump / 2.0); for (int i = 0; i < num_stations; ++i) { const oskar_Station* station = oskar_telescope_station_const(tel, i); double lon = oskar_station_lon_rad(station); double lat = oskar_station_lat_rad(station); double alt = oskar_station_alt_metres(station); double x_ecef, y_ecef, z_ecef, x_offset, y_offset, z_offset; if (type == OSKAR_DOUBLE) { x_offset = ((double*)x_)[i]; y_offset = ((double*)y_)[i]; z_offset = ((double*)z_)[i]; } else { x_offset = (double)((float*)x_)[i]; y_offset = (double)((float*)y_)[i]; z_offset = (double)((float*)z_)[i]; } oskar_convert_offset_ecef_to_ecef(1, &x_offset, &y_offset, &z_offset, lon, lat, alt, &x_ecef, &y_ecef, &z_ecef); double last = gast + lon; if (type == OSKAR_DOUBLE) { oskar_convert_apparent_ra_dec_to_enu_directions_d(num_sources, oskar_mem_double_const(oskar_sky_ra_rad_const(sky), &status), oskar_mem_double_const(oskar_sky_dec_rad_const(sky), &status), last, lat, oskar_mem_double(hor_x, &status), oskar_mem_double(hor_y, &status), oskar_mem_double(hor_z, &status)); } else { oskar_convert_apparent_ra_dec_to_enu_directions_f(num_sources, oskar_mem_float_const(oskar_sky_ra_rad_const(sky), &status), oskar_mem_float_const(oskar_sky_dec_rad_const(sky), &status), last, lat, oskar_mem_float(hor_x, &status), oskar_mem_float(hor_y, &status), oskar_mem_float(hor_z, &status)); } int offset = i * num_sources; oskar_mem_set_alias(pp_st_lon, pp_lon, offset, num_sources, &status); oskar_mem_set_alias(pp_st_lat, pp_lat, offset, num_sources, &status); oskar_mem_set_alias(pp_st_rel_path, pp_rel_path, offset, num_sources, &status); oskar_evaluate_pierce_points(pp_st_lon, pp_st_lat, pp_st_rel_path, x_ecef, y_ecef, z_ecef, screen_height_m, num_sources, hor_x, hor_y, hor_z, &status); } // Loop over stations. if (status != 0) continue; int index = t; // could be = (num_times * f) + t if we have frequency data int num_fields = 3; int num_field_tags = 4; double freq_hz = 0.0; int freq_idx = 0; // Write the header TAGS oskar_binary_write_int(h, GRP, TIME_IDX, index, t, &status); oskar_binary_write_double(h, GRP, FREQ_IDX, index, freq_idx, &status); oskar_binary_write_double(h, GRP, TIME_MJD_UTC, index, t_dump, &status); oskar_binary_write_double(h, GRP, FREQ_HZ, index, freq_hz, &status); oskar_binary_write_int(h, GRP, NUM_FIELDS, index, num_fields, &status); oskar_binary_write_int(h, GRP, NUM_FIELD_TAGS, index, num_field_tags, &status); // Write data TAGS (fields) int field, tagID; field = 0; tagID = HEADER_OFFSET + (num_field_tags * field); oskar_binary_write_mem(h, pp_lon, GRP, tagID + DATA, index, 0, &status); oskar_binary_write_mem(h, dims, GRP, tagID + DIMS, index, 0, &status); oskar_binary_write(h, OSKAR_CHAR, GRP, tagID + LABEL, index, label1.size()+1, label1.c_str(), &status); oskar_binary_write(h, OSKAR_CHAR, GRP, tagID + UNITS, index, units.size()+1, units.c_str(), &status); field = 1; tagID = HEADER_OFFSET + (num_field_tags * field); oskar_binary_write_mem(h, pp_lat, GRP, tagID + DATA, index, 0, &status); oskar_binary_write_mem(h, dims, GRP, tagID + DIMS, index, 0, &status); oskar_binary_write(h, OSKAR_CHAR, GRP, tagID + LABEL, index, label2.size()+1, label2.c_str(), &status); oskar_binary_write(h, OSKAR_CHAR, GRP, tagID + UNITS, index, units.size()+1, units.c_str(), &status); field = 2; tagID = HEADER_OFFSET + (num_field_tags * field); oskar_binary_write_mem(h, pp_rel_path, GRP, tagID + DATA, index, 0, &status); oskar_binary_write_mem(h, dims, GRP, tagID + DIMS, index, 0, &status); oskar_binary_write(h, OSKAR_CHAR, GRP, tagID + LABEL, index, label3.size()+1, label3.c_str(), &status); oskar_binary_write(h, OSKAR_CHAR, GRP, tagID + UNITS, index, units2.size()+1, units2.c_str(), &status); } // Loop over times // Close the OSKAR binary file. oskar_binary_free(h); // clean up memory oskar_mem_free(hor_x, &status); oskar_mem_free(hor_y, &status); oskar_mem_free(hor_z, &status); oskar_mem_free(pp_lon, &status); oskar_mem_free(pp_lat, &status); oskar_mem_free(pp_rel_path, &status); oskar_mem_free(pp_st_lon, &status); oskar_mem_free(pp_st_lat, &status); oskar_mem_free(pp_st_rel_path, &status); oskar_mem_free(dims, &status); oskar_telescope_free(tel, &status); oskar_sky_free(sky, &status); // Check for errors. if (status) oskar_log_error(log, "Run failed: %s.", oskar_get_error_string(status)); oskar_log_free(log); return status; }