astroimsim_data/
spatial_effect.rs1use std::time::Instant;
2use astroimsim_geometry::coordinate_system::Coordinates;
3use astroimsim_geometry::grid2d::{Corners, Location, GRID2D};
4use astroimsim_geometry::points::Point;
5use astroimsim_spectra::spectral_response::SpectralResponseCurve;
6use rand_distr;
7use uvex_fitrs::{Fits, FitsData, FitsDataArray};
8use uvex_fitrs::{ Hdu};
9use crate::psf::{DataFile, Load, PSF};
10
11#[derive(Clone,Debug)]
12pub struct SpatialEffect {
13 pub label: &'static str,
14 pub grid: GRID2D,
15 pub data: Vec<Vec<f64>>, pub fits_path: &'static str,
17}
18
19impl SpatialEffect{
20 pub fn new_empty(label:&'static str, grid:GRID2D,fits_path:&'static str)-> SpatialEffect{
21 SpatialEffect{label,grid,data:vec![],fits_path}
22 }
23 pub fn from_matrix(label:&'static str, grid:GRID2D,fits_path:&'static str,data:Vec<Vec<f64>>)-> SpatialEffect{
24 assert_eq!(grid.y_num,data.len());
25 for row in &data{ assert_eq!(grid.x_num, row.len()); }
26 SpatialEffect{label,grid,fits_path,data}
27 }
28
29
30 pub fn load_data(&mut self,trim:usize){
31 println!("Loading {:?} into {:?}",self.fits_path, self.label);
32 let fits = Fits::open(self.fits_path).expect("Failed to open FITS file");
33 let raw_data_x = self.grid.x_num+2*trim;
34 let raw_data_y = self.grid.y_num+2*trim;
35 let primary_hdu= fits.iter().next().expect("Couldn't find primary HDU");
36 let (mut data,shape) = match primary_hdu.read_data() {
37 FitsData::FloatingPoint64(FitsDataArray { shape, data }) => (data,shape),
38 FitsData::FloatingPoint32(FitsDataArray { shape, data }) => {
39 let data = data.iter().map(|x|*x as f64).collect();
40 (data,shape)},
41 _ => {panic!("huh? Couldn't load FITS file")}
42 };
43 assert_eq!(shape[0],raw_data_x,"FITS data had the wrong width");
44 assert_eq!(shape[1],raw_data_y,"FITS data had the wrong height");
45 let mut data:Vec<Vec<f64>> = data.chunks(raw_data_x).map(|v|{
46 v[trim..raw_data_x-trim].to_vec()
47 }).collect();
48 for delete_row in 0..trim{
49 data.remove(0);
50 data.pop();
51 };
52 self.data = data;
53
54 }
55
56
57 pub fn spawn_downsample(&self, grid2d: GRID2D)-> SpatialEffect{
58
59 let down_sampled_data:Vec<f64> =
60 (0..grid2d.num_points).map(|index|
61 {self.get_data(&grid2d.locate(index))}
63 ).collect();
64 let data:Vec<Vec<f64>> = down_sampled_data.chunks(grid2d.x_num)
65 .map(|v|v.to_vec()).collect();
66 println!("BEFORE {:?}", self.data[0][0]);
67 println!("After{:?}", data[0][0]);
68 SpatialEffect{
69 label: "downsampled data ", grid: grid2d,
71 data,
72 fits_path: "N/A", }
74 }
75
76
77 pub fn get_data_at_grid_index(&self, grid_number:usize)->f64{
78 let (x,y) = self.grid.xy_indices(grid_number);
79 self.data[y][x]
80 }
81
82
83 pub fn get_data(&self,point:&Point)->f64{
84 let interpolation_data = self.grid.projected_interpolation_coefficients(point);
85 let corners = match interpolation_data.corners{
88 Corners::Four(one, two, three, four) => {
89 vec![one,two,three,four]}
90 Corners::Two(one,two) => {vec![one,two]}
91 Corners::One(one) => {vec![one]}
92 };
93 let sum:f64 = corners
94 .into_iter().
95 zip(interpolation_data.coefficients)
96 .map(|(point,coefficient)|{
97 self.get_data_at_grid_index(point)*coefficient
98 }).sum();
99 sum/interpolation_data.normalization
100 }
101
102}
103
104
105
106
107