示例#1
0
static void free_device_data(oskar_Simulator* h, int* status)
{
    int i;
    if (!h->d) return;
    for (i = 0; i < h->num_devices; ++i)
    {
        DeviceData* d = &(h->d[i]);
        if (!d) continue;
        if (i < h->num_gpus)
            oskar_device_set(h->gpu_ids[i], status);
        oskar_timer_free(d->tmr_compute);
        oskar_timer_free(d->tmr_copy);
        oskar_timer_free(d->tmr_clip);
        oskar_timer_free(d->tmr_E);
        oskar_timer_free(d->tmr_K);
        oskar_timer_free(d->tmr_join);
        oskar_timer_free(d->tmr_correlate);
        oskar_vis_block_free(d->vis_block_cpu[0], status);
        oskar_vis_block_free(d->vis_block_cpu[1], status);
        oskar_vis_block_free(d->vis_block, status);
        oskar_mem_free(d->u, status);
        oskar_mem_free(d->v, status);
        oskar_mem_free(d->w, status);
        oskar_sky_free(d->chunk, status);
        oskar_sky_free(d->chunk_clip, status);
        oskar_telescope_free(d->tel, status);
        oskar_station_work_free(d->station_work, status);
        oskar_jones_free(d->J, status);
        oskar_jones_free(d->E, status);
        oskar_jones_free(d->K, status);
        oskar_jones_free(d->R, status);
        memset(d, 0, sizeof(DeviceData));
    }
}
void oskar_interferometer_free(oskar_Interferometer* h, int* status)
{
    int i;
    if (!h) return;
    oskar_interferometer_reset_cache(h, status);
    for (i = 0; i < h->num_gpus; ++i)
    {
        oskar_device_set(h->gpu_ids[i], status);
        oskar_device_reset();
    }
    for (i = 0; i < h->num_sky_chunks; ++i)
        oskar_sky_free(h->sky_chunks[i], status);
    oskar_telescope_free(h->tel, status);
    oskar_mem_free(h->temp, status);
    oskar_timer_free(h->tmr_sim);
    oskar_timer_free(h->tmr_write);
    oskar_mutex_free(h->mutex);
    oskar_barrier_free(h->barrier);
    free(h->sky_chunks);
    free(h->gpu_ids);
    free(h->vis_name);
    free(h->ms_name);
    free(h->settings_path);
    free(h->d);
    free(h);
}
void oskar_interferometer_set_sky_model(oskar_Interferometer* h,
        const oskar_Sky* sky, int* status)
{
    int i;
    if (*status || !h || !sky) return;

    /* Clear the old chunk set. */
    for (i = 0; i < h->num_sky_chunks; ++i)
        oskar_sky_free(h->sky_chunks[i], status);
    free(h->sky_chunks);
    h->sky_chunks = 0;
    h->num_sky_chunks = 0;

    /* Split up the sky model into chunks and store them. */
    h->num_sources_total = oskar_sky_num_sources(sky);
    if (h->num_sources_total > 0)
        oskar_sky_append_to_set(&h->num_sky_chunks, &h->sky_chunks,
                h->max_sources_per_chunk, sky, status);
    h->init_sky = 0;

    /* Print summary data. */
    if (h->log)
    {
        oskar_log_section(h->log, 'M', "Sky model summary");
        oskar_log_value(h->log, 'M', 0, "Num. sources", "%d",
                h->num_sources_total);
        oskar_log_value(h->log, 'M', 0, "Num. chunks", "%d",
                h->num_sky_chunks);
    }
}
示例#4
0
static PyObject* generate_random_power_law(PyObject* self, PyObject* args)
{
    oskar_Sky *h = 0;
    PyObject* capsule = 0;
    int prec, num_sources = 0, seed = 1, status = 0;
    const char* type = 0;
    double min_flux_jy = 0.0, max_flux_jy = 0.0, power = 0.0;
    if (!PyArg_ParseTuple(args, "idddis", &num_sources, &min_flux_jy,
            &max_flux_jy, &power, &seed, &type)) return 0;

    /* Generate the sources. */
    prec = (type[0] == 'S' || type[0] == 's') ? OSKAR_SINGLE : OSKAR_DOUBLE;
    h = oskar_sky_generate_random_power_law(prec, num_sources,
            min_flux_jy, max_flux_jy, power, seed, &status);

    /* Check for errors. */
    if (status)
    {
        PyErr_Format(PyExc_RuntimeError,
                "oskar_sky_generate_random_power_law() failed with code %d (%s).",
                status, oskar_get_error_string(status));
        oskar_sky_free(h, &status);
        return 0;
    }
    capsule = PyCapsule_New((void*)h, name, (PyCapsule_Destructor)sky_free);
    return Py_BuildValue("N", capsule); /* Don't increment refcount. */
}
示例#5
0
static PyObject* generate_grid(PyObject* self, PyObject* args)
{
    oskar_Sky *h = 0;
    PyObject* capsule = 0;
    int prec, side_length = 0, seed = 1, status = 0;
    const char* type = 0;
    double ra0, dec0, fov, mean_flux_jy, std_flux_jy;
    if (!PyArg_ParseTuple(args, "ddidddis", &ra0, &dec0, &side_length,
            &fov, &mean_flux_jy, &std_flux_jy, &seed, &type)) return 0;

    /* Generate the grid. */
    prec = (type[0] == 'S' || type[0] == 's') ? OSKAR_SINGLE : OSKAR_DOUBLE;
    ra0 *= M_PI / 180.0;
    dec0 *= M_PI / 180.0;
    fov *= M_PI / 180.0;
    h = oskar_sky_generate_grid(prec, ra0, dec0, side_length, fov,
            mean_flux_jy, std_flux_jy, seed, &status);

    /* Check for errors. */
    if (status)
    {
        PyErr_Format(PyExc_RuntimeError,
                "oskar_sky_generate_grid() failed with code %d (%s).",
                status, oskar_get_error_string(status));
        oskar_sky_free(h, &status);
        return 0;
    }
    capsule = PyCapsule_New((void*)h, name, (PyCapsule_Destructor)sky_free);
    return Py_BuildValue("N", capsule); /* Don't increment refcount. */
}
示例#6
0
 void destroyTestData()
 {
     int status = 0;
     oskar_jones_free(jones, &status);
     oskar_mem_free(u_, &status);
     oskar_mem_free(v_, &status);
     oskar_mem_free(w_, &status);
     oskar_sky_free(sky, &status);
     oskar_telescope_free(tel, &status);
     ASSERT_EQ(0, status) << oskar_get_error_string(status);
 }
示例#7
0
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;
}
int main(int argc, char** argv)
{
    int error = 0;

    oskar::OptionParser opt("oskar_fits_image_to_sky_model",
            oskar_version_string());
    opt.set_description("Converts a FITS image to an OSKAR sky model. A number "
            "of options are provided to control how much of the image is used "
            "to make the sky model.");
    opt.add_required("FITS file", "The input FITS image to convert.");
    opt.add_required("sky model file", "The output OSKAR sky model file name to save.");
    opt.add_flag("-s", "Spectral index. This is the spectral index that will "
            "be given to each pixel in the output sky model.", 1, "0.0");
    opt.add_flag("-f", "Minimum allowed fraction of image peak. Pixel values "
            "below this fraction will be ignored.", 1, "0.0");
    opt.add_flag("-n", "Noise floor in units of original image. "
            "Pixels below this value will be ignored.", 1, "0.0");
    if (!opt.check_options(argc, argv)) return EXIT_FAILURE;

    // Parse command line.
    double spectral_index = 0.0;
    double min_peak_fraction = 0.0;
    double min_abs_val = 0.0;
    opt.get("-f")->getDouble(min_peak_fraction);
    opt.get("-n")->getDouble(min_abs_val);
    opt.get("-s")->getDouble(spectral_index);

    // Load the FITS image data.
    oskar_Sky* sky = oskar_sky_from_fits_file(OSKAR_DOUBLE, opt.get_arg(0),
            min_peak_fraction, min_abs_val, "Jy/beam", 0, 0.0, spectral_index,
            &error);

    // Write out the sky model.
    oskar_sky_save(opt.get_arg(1), sky, &error);
    if (error)
    {
        oskar_log_error(0, oskar_get_error_string(error));
        return error;
    }

    oskar_sky_free(sky, &error);
    return 0;
}
示例#9
0
void oskar_simulator_set_sky_model(oskar_Simulator* h, const oskar_Sky* sky,
        int max_sources_per_chunk, int* status)
{
    int i;
    if (*status) return;

    /* Clear the old chunk set. */
    for (i = 0; i < h->num_sky_chunks; ++i)
        oskar_sky_free(h->sky_chunks[i], status);
    free(h->sky_chunks);
    h->sky_chunks = 0;
    h->num_sky_chunks = 0;

    /* Split up the sky model into chunks and store them. */
    h->max_sources_per_chunk = max_sources_per_chunk;
    if (oskar_sky_num_sources(sky) > 0)
        oskar_sky_append_to_set(&h->num_sky_chunks, &h->sky_chunks,
                max_sources_per_chunk, sky, status);
    h->init_sky = 0;
}
示例#10
0
static PyObject* create_copy(PyObject* self, PyObject* args)
{
    oskar_Sky *h = 0, *t = 0;
    PyObject* capsule = 0;
    int status = 0;
    if (!PyArg_ParseTuple(args, "O", &capsule)) return 0;
    if (!(h = get_handle(capsule))) return 0;
    t = oskar_sky_create_copy(h, OSKAR_CPU, &status);

    /* Check for errors. */
    if (status || !t)
    {
        PyErr_Format(PyExc_RuntimeError,
                "oskar_sky_create_copy() failed with code %d (%s).",
                status, oskar_get_error_string(status));
        oskar_sky_free(t, &status);
        return 0;
    }

    capsule = PyCapsule_New((void*)t, name, (PyCapsule_Destructor)sky_free);
    return Py_BuildValue("N", capsule); /* Don't increment refcount. */
}
示例#11
0
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("");
}
示例#12
0
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;
}
示例#13
0
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;
}
示例#14
0
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);
}
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;
}
示例#16
0
static void sky_free(PyObject* capsule)
{
    int status = 0;
    oskar_Sky* h = (oskar_Sky*) PyCapsule_GetPointer(capsule, name);
    oskar_sky_free(h, &status);
}