-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
mwa_pb and the RTS disagree on how the beam is implemented, so both versions are available. You're welcome. A future release should rename the FEE FFI functions to be unambiguously to do with FEE (e.g. calc_jones -> fee_calc_jones). This is not done here so we don't break semver. The `mut` requirement on `self` for python functions has been removed. Similarly, the FEE FFI beam is no longer accessed as mutable. I'm pretty sure this doesn't change anything.
- Loading branch information
Showing
43 changed files
with
4,647 additions
and
448 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
// This Source Code Form is subject to the terms of the Mozilla Public | ||
// License, v. 2.0. If a copy of the MPL was not distributed with this | ||
// file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||
|
||
// Build and run with something like: | ||
// gcc -O3 -I ../include/ -L ../target/release/ -l mwa_hyperbeam ./analytic.c -o analytic | ||
// LD_LIBRARY_PATH=../target/release ./analytic | ||
|
||
#include <complex.h> | ||
#include <math.h> | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
|
||
#include "mwa_hyperbeam.h" | ||
|
||
void handle_hyperbeam_error(char file[], int line_num, const char function_name[]) { | ||
int err_length = hb_last_error_length(); | ||
char *err = malloc(err_length * sizeof(char)); | ||
int err_status = hb_last_error_message(err, err_length); | ||
if (err_status == -1) { | ||
printf("Something really bad happened!\n"); | ||
exit(EXIT_FAILURE); | ||
} | ||
printf("File %s:%d: hyperbeam error in %s: %s\n", file, line_num, function_name, err); | ||
|
||
exit(EXIT_FAILURE); | ||
} | ||
|
||
int main(int argc, char *argv[]) { | ||
// Get a new beam object from hyperbeam. | ||
AnalyticBeam *beam; | ||
char rts_style = 0; // 1 or RTS style, 0 for mwa_pb | ||
double *dipole_height_metres = NULL; // Point to a valid float if you want a custom height | ||
if (new_analytic_beam(rts_style, dipole_height_metres, &beam)) | ||
handle_hyperbeam_error(__FILE__, __LINE__, "new_analytic_beam"); | ||
|
||
// Set up the direction and pointing to test. | ||
double az = 45.0 * M_PI / 180.0; | ||
double za = 80.0 * M_PI / 180.0; | ||
// Delays and amps correspond to dipoles in the "M&C order". See | ||
// https://wiki.mwatelescope.org/pages/viewpage.action?pageId=48005139) for | ||
// more info. Amps refer to dipole gains, and are usually set to 1 or 0 (if | ||
// a dipole is dead). | ||
unsigned delays[16] = {3, 2, 1, 0, 3, 2, 1, 0, 3, 2, 1, 0, 3, 2, 1, 0}; | ||
double amps[16] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1}; | ||
int freq_hz = 51200000; | ||
// MWA latitude | ||
double latitude_rad = -0.4660608448386394; | ||
// Should we normalise the beam response? | ||
int norm_to_zenith = 1; | ||
|
||
// Calculate the Jones matrix for this direction and pointing. This Jones | ||
// matrix is on the stack. | ||
complex double jones[4]; | ||
// hyperbeam expects a pointer to doubles. Casting the pointer works fine. | ||
if (analytic_calc_jones(beam, az, za, freq_hz, delays, amps, 16, latitude_rad, norm_to_zenith, (double *)&jones)) | ||
handle_hyperbeam_error(__FILE__, __LINE__, "analytic_calc_jones"); | ||
|
||
printf("The returned Jones matrix:\n"); | ||
printf("[[%+.8f%+.8fi,", creal(jones[0]), cimag(jones[0])); | ||
printf(" %+.8f%+.8fi]\n", creal(jones[1]), cimag(jones[1])); | ||
printf(" [%+.8f%+.8fi,", creal(jones[2]), cimag(jones[2])); | ||
printf(" %+.8f%+.8fi]]\n", creal(jones[3]), cimag(jones[3])); | ||
|
||
// Amps can have 32 elements to specify amps of the X and Y dipoles. The | ||
// first 16 elements are X amps, the second 16 are Y amps. | ||
double amps_2[32] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, | ||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; | ||
// This Jones matrix is on the heap. | ||
complex double *jones_2 = malloc(4 * sizeof(complex double)); | ||
if (analytic_calc_jones(beam, az, za, freq_hz, delays, amps_2, 32, latitude_rad, norm_to_zenith, (double *)jones_2)) | ||
handle_hyperbeam_error(__FILE__, __LINE__, "analytic_calc_jones"); | ||
|
||
// The resulting Jones matrix has different elements on the second row, | ||
// corresponding to the Y element; this is because we only altered the Y | ||
// amps. | ||
printf("The returned Jones matrix with altered Y amps:\n"); | ||
printf("[[%+.8f%+.8fi,", creal(jones_2[0]), cimag(jones_2[0])); | ||
printf(" %+.8f%+.8fi]\n", creal(jones_2[1]), cimag(jones_2[1])); | ||
printf(" [%+.8f%+.8fi,", creal(jones_2[2]), cimag(jones_2[2])); | ||
printf(" %+.8f%+.8fi]]\n", creal(jones_2[3]), cimag(jones_2[3])); | ||
|
||
// Free the heap-allocated Jones matrix. | ||
free(jones_2); | ||
// Free the beam - we must use a special function to do this. | ||
free_analytic_beam(beam); | ||
|
||
return EXIT_SUCCESS; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
#!/usr/bin/env python | ||
|
||
# This Source Code Form is subject to the terms of the Mozilla Public | ||
# License, v. 2.0. If a copy of the MPL was not distributed with this | ||
# file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||
|
||
import sys | ||
import time | ||
import numpy as np | ||
import mwa_hyperbeam | ||
|
||
if len(sys.argv) > 1 and sys.argv[1] == "rts": | ||
beam = mwa_hyperbeam.AnalyticBeam(rts_behaviour=True) | ||
else: | ||
beam = mwa_hyperbeam.AnalyticBeam() | ||
|
||
# Make a lot of directions for hyperbeam to calculate in parallel. | ||
n = 1000000 | ||
az = np.linspace(0, 0.9 * np.pi, n) | ||
za = np.linspace(0.1, 0.9 * np.pi / 2, n) | ||
freq = 167000000 | ||
# Delays and amps correspond to dipoles in the "M&C order". See | ||
# https://wiki.mwatelescope.org/pages/viewpage.action?pageId=48005139) for more | ||
# info. | ||
delays = [0] * 16 | ||
amps = [1.0] * 16 | ||
# Should we normalise the beam response? | ||
norm_to_zenith = True | ||
|
||
# Pass the values to hyperbeam and get a numpy array back. Each element is a | ||
# 4-element Jones matrix. | ||
start_time = time.time() | ||
# beam.calc_jones is also available, but that makes a single Jones matrix at a | ||
# time, so one would need to iterate over az and za. calc_jones_array is done in | ||
# parallel with Rust (so it's fast). | ||
jones = beam.calc_jones_array(az, za, freq, delays, amps, norm_to_zenith) | ||
duration = time.time() - start_time | ||
print("Time to calculate {} directions: {:.3}s".format(n, duration)) | ||
print("First Jones matrix:") | ||
print(jones[0]) | ||
|
||
# It's also possible to supply amps for all dipole elements. The first 16 amps | ||
# are for X elements, the second 16 are for Y elements. | ||
amps = np.ones(32) | ||
amps[-1] = 0 | ||
jones = beam.calc_jones_array(az[:1], za[:1], freq, delays, amps, norm_to_zenith) | ||
print("First Jones matrix with altered Y amps:") | ||
print(jones[0]) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
// This Source Code Form is subject to the terms of the Mozilla Public | ||
// License, v. 2.0. If a copy of the MPL was not distributed with this | ||
// file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||
|
||
//! Example of using hyperbeam analytic beam code with Rust. | ||
//! | ||
//! Build and run with something like: | ||
//! `cargo run --release --example analytic -- 10000` | ||
//! | ||
//! If you want to use hyperbeam in your own Rust crate, then check out the latest | ||
//! version on crates.io: | ||
//! | ||
//! https://crates.io/crates/mwa_hyperbeam | ||
|
||
use std::f64::consts::{FRAC_PI_2, PI}; | ||
|
||
use mwa_hyperbeam::{analytic::AnalyticBeam, AzEl}; | ||
|
||
fn main() { | ||
if let Err(e) = try_main() { | ||
eprintln!("Error: {e}"); | ||
std::process::exit(1); | ||
} | ||
} | ||
|
||
fn try_main() -> Result<(), Box<dyn std::error::Error>> { | ||
let mut args = std::env::args().skip(1); | ||
let num_directions: usize = args | ||
.next() | ||
.expect("number of directions supplied") | ||
.parse() | ||
.expect("number of directions is a number"); | ||
|
||
// `AnalyticBeam::new` gives the default beam (in this case, matching | ||
// `mwa_pb` behaviour), but `AnalyticBeam::new_rts` also exists. | ||
let beam = AnalyticBeam::new(); | ||
|
||
// Set up the directions to test. | ||
let mut azels = vec![]; | ||
for i in 0..num_directions { | ||
let az = 0.9 * PI * i as f64 / num_directions as f64; | ||
let za = 0.1 + 0.9 * PI / 2.0 * i as f64 / num_directions as f64; | ||
azels.push(AzEl::from_radians(az, FRAC_PI_2 - za)); | ||
} | ||
let freq_hz = 51200000; | ||
// Delays and amps correspond to dipoles in the "M&C order". See | ||
// https://wiki.mwatelescope.org/pages/viewpage.action?pageId=48005139) for | ||
// more info. | ||
let delays = [0; 16]; | ||
assert_eq!(delays.len(), 16); | ||
let amps = [1.0; 16]; | ||
assert!(amps.len() == 16 || amps.len() == 32); | ||
let latitude_rad = -0.4660608448386394; // MWA | ||
let norm_to_zenith = true; | ||
|
||
// Call hyperbeam. | ||
let jones = beam.calc_jones_array( | ||
&azels, | ||
freq_hz, | ||
&delays, | ||
&s, | ||
latitude_rad, | ||
norm_to_zenith, | ||
)?; | ||
println!("The first Jones matrix:"); | ||
// This works, but the formatting for this isn't very pretty. | ||
// println!("{}", jones[0]); | ||
|
||
// For demonstrations' sake, this gives easier-to-read output. | ||
let j = jones[0]; | ||
println!( | ||
"[[{:+.8}, {:+.8}]\n [{:+.8}, {:+.8}]]", | ||
j[0], j[1], j[2], j[3] | ||
); | ||
|
||
Ok(()) | ||
} |
Oops, something went wrong.