Skip to main content

astroimsim_data/
spatial_effect.rs

1use std::time::Instant;
2use astroimsim_geometry::coordinate_system::Coordinates;
3use astroimsim_geometry::grid2d::{Location, GRID2D};
4use astroimsim_geometry::points::Point;
5use astroimsim_spectra::spectral_response::SpectralResponseCurve;
6
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    
24    pub fn from_matrix(label:&'static str, grid:GRID2D,fits_path:&'static str,data:Vec<Vec<f64>>)-> SpatialEffect{
25        assert_eq!(grid.y_num,data.len());
26        for row in &data{ assert_eq!(grid.x_num, row.len()); }
27        SpatialEffect{label,grid,fits_path,data}
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       let sum:f64 = interpolation_data.corners
87           .iter()
88           .zip(interpolation_data.coefficients)
89           .map(|(point,coefficient)|{
90               self.get_data_at_grid_index(*point)*coefficient
91           }).sum();
92       sum/interpolation_data.normalization
93   }
94    
95}
96
97
98
99
100