-
Handle dates in multiple standard & astronomical formats:
use chrono::{Utc, TimeZone};
use flare::Time;
fn main() {
let time = Time::new(2021, 6, 21, 12, 0, 0);
let time_jd = time.to_jd();
println!("The Julian Date of the time is: {}", time_jd);
let time_from_jd = Time::from_jd(2459376.0);
println!("The time from the Julian Date is: {}", time_from_jd);
let current_time = Time::now();
println!("{}", current_time);
let chrono_utc = Utc.with_ymd_and_hms(2020, 1, 1, 0, 0, 0).unwrap();
let time = Time::from_utc(chrono_utc);
println!("{}", time.to_string(Some("mjd")));
}
-
Calculate the angular separation between two targets/objects in the sky:
use flare::Target;
fn main() {
let target1 = Target::new(6.374817, 20.242942, Some("A"));
let target2 = Target::new(6.374817, 21.242942, Some("B"));
let separation = target1.separation(&target2);
println!("The angular separation between the two targets is: {}", separation);
}
-
Given an observer on earth, find the airmass of a target (at a given time):
use flare::{Target, Observer, Time};
fn main() {
let observer = Observer::new(30.0, 45.0, 1800.0, Some("A"));
println!("{}", observer);
let target = Target::new(6.374817, 20.242942, Some("B"));
println!("{}", target);
let time = Time::new(2020, 12, 21, 12, 0, 0);
println!("{}", time);
let airmass = target.airmass(&observer, &time);
println!("Airmass at {} is: {}", time, airmass);
}
-
For an observer, find the next sunrise & sunset times (after a given time):
use flare::{Observer, Time};
fn main() {
let observer = Observer::new(33.3633675, -116.8361345, 1870.0, None);
println!("{}", observer);
let time = Time::new(2024, 9, 10, 3, 0, 0);
println!("{}", time);
let (sunrise, sunset) = observer.sun_set_time(Some(&time), None);
println!("Next sunrise: {}", sunrise);
println!("Next sunset: {}", sunset);
let (sunrise, sunset) = observer.sun_set_time(None, None);
println!("Sunrise: {}, Sunset: {}", sunrise, sunset);
let (sunrise, sunset) = observer.sun_set_time(Some(&time), Some(0.0));
println!("Sunrise: {}, Sunset: {} (at 0.0 deg)", sunrise, sunset);
let (sunrise, sunset) = observer.twilight_astronomical(Some(&time));
println!("Sunrise: {}, Sunset: {} (astronomical)", sunrise, sunset);
let (sunrise, sunset) = observer.twilight_nautical(Some(&time));
println!("Sunrise: {}, Sunset: {} (nautical)", sunrise, sunset);
let (sunrise, sunset) = observer.twilight_civil(Some(&time));
println!("Sunrise: {}, Sunset: {} (civil)", sunrise, sunset);
}
-
Work with photometry, in mag and flux space:
use flare::phot::{mag_to_flux, flux_to_mag, limmag_to_fluxerr, fluxerr_to_limmag, ZP};
fn main() {
let mag = 20.0;
let magerr = 0.1;
let limmag = 21.0;
let (flux, fluxerr) = mag_to_flux(mag, magerr, ZP);
println!("flux: {}, fluxerr: {}", flux, fluxerr);
let (mag, magerr) = flux_to_mag(flux, fluxerr, ZP);
println!("mag: {}, mag: {}", mag, magerr);
let fluxerr = limmag_to_fluxerr(limmag, ZP, 5.0);
println!("fluxerr (from limmag): {}", fluxerr);
let limmag = fluxerr_to_limmag(fluxerr, ZP, 5.0);
println!("limmag (from fluxerr, at 5-sigma): {}", limmag);
let limmag = limmag_to_fluxerr(limmag, 25.0, 3.0);
println!("fluxerr (from limmag, 3-sigma & ZP=25.0): {}", limmag);
}
-
Use a cosmology (custom, or one of the built-in ones) to compute distances:
use flare::Cosmo;
fn main() {
let z = 0.1;
let cosmo = Cosmo::planck18();
let luminosity_distance = cosmo.luminosity_distance(z);
println!("Luminosity distance: {}", luminosity_distance);
let dm = cosmo.dm(z);
println!("Distance modulus: {}", dm);
let angular_diameter_distance = cosmo.angular_diameter_distance(z);
println!("Angular diameter distance: {}", angular_diameter_distance);
let apparent_mag = 20.0;
let abs_mag = apparent_mag - dm;
println!("{} mag at z={} is {}", apparent_mag, z, abs_mag);
let cosmology = Cosmo::new(67.66, 0.3103, 0.6897, Some("mycosmo"));
let z = 0.0246;
let dm = cosmology.dm(z);
println!("Distance modulus at z={} (using custom cosmology {}) is {}", z, cosmology.name.unwrap(), dm);
}
-
Look for a periodic in a lightcurve:
use flare::period::{fpw, freq_grid, get_best_freq};
use rand::Rng;
fn main() {
let n_points = 1000;
let period = 0.25;
let mut rng = rand::rng();
let mut t: Vec<f64> = Vec::with_capacity(n_points);
for _ in 0..n_points {
let random_time = rng.random_range(0.0..(6.0 * 365.0));
t.push(random_time);
}
t.sort_by(|a, b| a.partial_cmp(b).unwrap_or(std::cmp::Ordering::Equal));
let noise_level = 0.1; let y: Vec<f64> = t
.iter()
.map(|&time| {
let true_value = (2.0 * std::f64::consts::PI * time / period).sin();
let noise = rng.random_range(-noise_level..noise_level);
true_value + noise
})
.collect();
let f_min = 1.0 / (10.0 * 24.0 * 60.0);
let f_max = 1.0 / (5.0 / 60.0);
let freqs = freq_grid(&t, Some(f_min), Some(f_max), 3);
println!("Using {} frequencies", freqs.len());
let n_bins = 10; let fpw_stats = fpw(&t, &y, &vec![0.1; n_points], &freqs, n_bins);
let (best_freq, best_stat) = get_best_freq(&freqs, &fpw_stats);
let period = 1.0 / best_freq * 24.0;
println!("Period: {:.2} hours, statistic: {:.2}", period, best_stat);
}
We welcome contributions! No specific guidelines yet, but feel free to open an issue or a PR. Keep in mind that the goal is to keep this library lightweight and focused on basic astronomical calculations. We are not trying to replicate the functionality of Astropy in Rust.