Skip to main content

astroimsim_data/
spatial_effect.rs

1use 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>>, //data must be fractional - implement percent later?
16    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            {//println!("value at index {:?} is  {:?}, location {:?}", index,self.get_data(&grid2d.locate(index)),grid2d.locate(index) );
62                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 ", //TODO
70            grid: grid2d,
71            data,
72            fits_path: "N/A", //TODO: path enheritance
73        }
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       //println!("{:?}",interpolation_data.corners.len());
86
87       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