void oskar_imager_finalise(oskar_Imager* h, int num_output_images, oskar_Mem** output_images, int num_output_grids, oskar_Mem** output_grids, int* status) { int t, c, p, i; if (*status || !h->planes) return; /* Adjust normalisation if required. */ if (h->scale_norm_with_num_input_files) { for (i = 0; i < h->num_planes; ++i) h->plane_norm[i] /= h->num_files; } /* Copy grids to output grid planes if given. */ for (i = 0; (i < h->num_planes) && (i < num_output_grids); ++i) { oskar_mem_copy(output_grids[i], h->planes[i], status); oskar_mem_scale_real(output_grids[i], 1.0 / h->plane_norm[i], status); } /* Check if images are required. */ if (h->fits_file[0] || output_images) { /* Finalise all the planes. */ for (i = 0; i < h->num_planes; ++i) { oskar_imager_finalise_plane(h, h->planes[i], h->plane_norm[i], status); oskar_imager_trim_image(h->planes[i], h->grid_size, h->image_size, status); } /* Copy images to output image planes if given. */ for (i = 0; (i < h->num_planes) && (i < num_output_images); ++i) { memcpy(oskar_mem_void(output_images[i]), oskar_mem_void_const(h->planes[i]), h->image_size * h->image_size * oskar_mem_element_size(h->imager_prec)); } /* Write to files if required. */ for (t = 0, i = 0; t < h->im_num_times; ++t) for (c = 0; c < h->im_num_channels; ++c) for (p = 0; p < h->im_num_pols; ++p, ++i) write_plane(h, h->planes[i], t, c, p, status); } /* Reset imager memory. */ oskar_imager_reset_cache(h, status); }
TEST(imager, grid_sum) { int status = 0, type = OSKAR_DOUBLE; int size = 2048, grid_size = size * size; // Create and set up the imager. oskar_Imager* im = oskar_imager_create(type, &status); oskar_imager_set_grid_kernel(im, "pillbox", 1, 1, &status); oskar_imager_set_fov(im, 5.0); oskar_imager_set_size(im, size, &status); oskar_Mem* grid = oskar_mem_create(type | OSKAR_COMPLEX, OSKAR_CPU, grid_size, &status); ASSERT_EQ(0, status); // Create visibility data. int num_vis = 10000; oskar_Mem* uu = oskar_mem_create(type, OSKAR_CPU, num_vis, &status); oskar_Mem* vv = oskar_mem_create(type, OSKAR_CPU, num_vis, &status); oskar_Mem* ww = oskar_mem_create(type, OSKAR_CPU, num_vis, &status); oskar_Mem* vis = oskar_mem_create(type | OSKAR_COMPLEX, OSKAR_CPU, num_vis, &status); oskar_Mem* weight = oskar_mem_create(type, OSKAR_CPU, num_vis, &status); oskar_mem_random_gaussian(uu, 0, 1, 2, 3, 100.0, &status); oskar_mem_random_gaussian(vv, 4, 5, 6, 7, 100.0, &status); oskar_mem_set_value_real(vis, 1.0, 0, num_vis, &status); oskar_mem_set_value_real(weight, 1.0, 0, num_vis, &status); // Grid visibility data. double plane_norm = 0.0; oskar_imager_update_plane(im, num_vis, uu, vv, ww, vis, weight, grid, &plane_norm, 0, &status); ASSERT_DOUBLE_EQ((double)num_vis, plane_norm); // Sum the grid. double2* t = oskar_mem_double2(grid, &status); double sum = 0.0; for (int i = 0; i < grid_size; i++) sum += t[i].x; ASSERT_DOUBLE_EQ((double)num_vis, sum); // Finalise the image. oskar_imager_finalise_plane(im, grid, plane_norm, &status); ASSERT_EQ(0, status); #ifdef WRITE_FITS // Get the real part only. if (oskar_mem_precision(grid) == OSKAR_DOUBLE) { double *t = oskar_mem_double(grid, &status); for (int j = 0; j < grid_size; ++j) t[j] = t[2 * j]; } else { float *t = oskar_mem_float(grid, &status); for (int j = 0; j < grid_size; ++j) t[j] = t[2 * j]; } // Save the real part. fitsfile* f; long naxes[2] = {size, size}, firstpix[2] = {1, 1}; fits_create_file(&f, "test_imager_grid_sum.fits", &status); fits_create_img(f, (type == OSKAR_DOUBLE ? DOUBLE_IMG : FLOAT_IMG), 2, naxes, &status); fits_write_pix(f, (type == OSKAR_DOUBLE ? TDOUBLE : TFLOAT), firstpix, grid_size, oskar_mem_void(grid), &status); fits_close_file(f, &status); #endif // Clean up. oskar_imager_free(im, &status); oskar_mem_free(uu, &status); oskar_mem_free(vv, &status); oskar_mem_free(ww, &status); oskar_mem_free(vis, &status); oskar_mem_free(weight, &status); oskar_mem_free(grid, &status); }