1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
use std::fs::File;
use std::io::Write;
use std::time::Instant;
use rand::distr::{Distribution, Uniform};
use serde::Serialize;
use astroimsim_geometry::grid2d::{Location, GRID2D};
use astroimsim_geometry::points::Point;
use crate::units::Units;
pub const spectral_resolution:usize = 1000;
#[derive( Clone, Debug)]
pub enum Spectrum{
Full(f64,[f64;spectral_resolution], Units),
Bands(Vec<Bands>, Units),
}
#[derive(Clone,Debug)]
pub enum Bands{
FUV(f64),
NUV(f64),
}
#[derive(Debug,Clone)]
pub struct PointSource {
pub point: Point,
pub spectrum: Spectrum,
}
impl PointSource {
pub fn new_full(point:Point, spectrum: [f64;spectral_resolution],luminosity:f64, units: Units) -> PointSource {
let spectrum = Spectrum::Full(luminosity,spectrum, units);
PointSource {
point,
spectrum
}
}
pub fn new_fuv_nuv(point:Point,fuv:f64,nuv:f64,units: Units ) -> PointSource{
let spectrum = Spectrum::Bands(vec![Bands::NUV(nuv),Bands::FUV(fuv)],units);
PointSource{
point,
spectrum
}
}
pub fn new(point:Point, spectrum: Spectrum) -> PointSource{
PointSource{
point,
spectrum,
}
}
pub fn fake_spectrum()-> [f64;spectral_resolution]{
let mut spectrum = [0.0;spectral_resolution];
let luminosities = Uniform::new(0.0,1.0).expect("Could not generate random luminosities in the given range");
let mut rng = rand::rng();
for element in 0..spectrum.len(){
spectrum[element] = 1.0 + luminosities.sample(&mut rng);
}
/*
Spectrum::Full(1.0,spectrum)
*/
spectrum
}
pub fn fake_bands(units: Units) -> Spectrum{
let luminosities = Uniform::new(0.0,1.0).expect("Could not generate random luminosities in the given range");
let mut rng = rand::rng();
Spectrum::Bands(vec![Bands::FUV(luminosities.sample(&mut rng)),Bands::NUV(luminosities.sample(&mut rng))],units)
}
pub fn scale(&mut self,scale:f64){
match &self.spectrum{
Spectrum::Full(l, c,u) => {self.spectrum = Spectrum::Full(l*scale,*c,(*u).clone())}
Spectrum::Bands(bands,u) => {
self.spectrum = Spectrum::Bands(bands.iter().map(|band|
match band {
Bands::FUV(l) => { Bands::FUV(l * scale) }
Bands::NUV(l) => { Bands::FUV(l * scale) }
}).collect(),(*u).clone() )
}
};
}
}
#[derive(Debug)]
pub struct SourceList {
pub sources: Vec<PointSource>,
}
impl SourceList {
pub fn new_from(mut sources:Vec<PointSource> ) -> SourceList {
//sources.sort_by(|a:&point_source, b:&point_source| b.bin.cmp(&a.bin));
SourceList {
sources,
}
}
pub fn new_empty(capacity:usize) -> SourceList {
SourceList {
sources: Vec::with_capacity(capacity)
}
}
pub fn add_source(&mut self, source: PointSource) -> &mut SourceList {
self.sources.push(source);
self
}
pub fn random_full_spectrum_point_source_field(number_of_point_sources:usize,
min_brightness: f64,
max_brightness: f64,
grid: &GRID2D,
units: Units
) -> SourceList {
//Some checks to make sure that the incoming values are as expected
//TODO Fix these checks to work with f64 values
/*
for end_point in [min_brightness,max_brightness,min_x,max_x,min_y,max_y]{
assert!((0.0 <= end_point) || (end_point <= 1.0),"{}: {} must be a float between 0 and 1",stringify!(end_point),end_point );
}
assert!(min_brightness <= max_brightness,"min_brightness must be less than or equal to max_brightness");
assert!(min_x <= max_x,"min_x must be less than or equal to max_x");
assert!(min_y <= max_y,"min_y must be less than or equal to max_y");
*/
let luminosities = Uniform::new(min_brightness,max_brightness).expect("Could not generate random luminosities in the given range");
let mut rng = rand::rng();
let sources: Vec<PointSource> = (0..number_of_point_sources).map(|_x|{
let luminosity = luminosities.sample(&mut rng);
let point = grid.random();
// println!("Point is {:?}",point);
let spectrum = PointSource::fake_spectrum();
PointSource::new_full(point,spectrum,luminosity,units.clone())
}).collect();
SourceList::new_from(sources)
}
/*
pub fn write_to_yaml(&self, file_name:&str,) {
println!("Serializing point sources");
let serialized_self = serde_yaml::to_string(&self).expect("Failed to YAMLify the sources");
let mut file = File::create(file_name).expect("Couldn't create the config file");
write!(file, "{}", serialized_self).expect("Failed to write YAML to config file");
}
*/
pub fn random_bands_point_source_field(number_of_point_sources:usize,
min_brightness: f64,
max_brightness: f64,
units: Units,
grid: &GRID2D,
) -> SourceList {
//Some checks to make sure that the incoming values are as expected
//TODO Fix these checks to work with f64 values
/*
for end_point in [min_brightness,max_brightness,min_x,max_x,min_y,max_y]{
assert!((0.0 <= end_point) || (end_point <= 1.0),"{}: {} must be a float between 0 and 1",stringify!(end_point),end_point );
}
assert!(min_brightness <= max_brightness,"min_brightness must be less than or equal to max_brightness");
assert!(min_x <= max_x,"min_x must be less than or equal to max_x");
assert!(min_y <= max_y,"min_y must be less than or equal to max_y");
*/
let luminosities = Uniform::new(min_brightness,max_brightness).expect("Could not generate random luminosities in the given range");
let mut rng = rand::rng();
let sources: Vec<PointSource> = (0..number_of_point_sources).map(|_x|{
let point = grid.random();
let spectrum = PointSource::fake_bands(units.clone());
PointSource { point, spectrum }
}).collect();
SourceList::new_from(sources)
}
/*
pub fn write_to_yaml(&self, file_name:&str,) {
println!("Serializing point sources");
let serialized_self = serde_yaml::to_string(&self).expect("Failed to YAMLify the sources");
let mut file = File::create(file_name).expect("Couldn't create the config file");
write!(file, "{}", serialized_self).expect("Failed to write YAML to config file");
}
*/
/*
pub fn apply_flatfield_illumination(&mut self,illumination:flatfield){
let start = Instant::now();
for source in &mut self.sources{
let scale = match illumination.grid.inside_or_outside(&source.point){
Location::Outside => {continue}
Location::Inside => {
let (x_mod,y_mod,_x_residual,_y_residual) = illumination.grid.fit_grid(&source.point);
illumination.data[y_mod][x_mod]
}
};
// println!("Scle is {scale}");
source.scale(scale)
}
println!("Applied flatfield illumination to {:?} sources in {:?}ms",self.sources.len(),start.elapsed().as_millis())
}
*/
}