lightstack 0.1.0__tar.gz → 0.1.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Andressa Wille, Thallis Pessi
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,64 @@
1
+ Metadata-Version: 2.1
2
+ Name: lightstack
3
+ Version: 0.1.2
4
+ Summary: Tools for building and processing multi-filter astrophysical datacubes
5
+ Author: Andressa Wille, Thallis Pessi
6
+ License: MIT License
7
+
8
+ Copyright (c) 2026 Andressa Wille, Thallis Pessi
9
+
10
+ Permission is hereby granted, free of charge, to any person obtaining a copy
11
+ of this software and associated documentation files (the "Software"), to deal
12
+ in the Software without restriction, including without limitation the rights
13
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
+ copies of the Software, and to permit persons to whom the Software is
15
+ furnished to do so, subject to the following conditions:
16
+
17
+ The above copyright notice and this permission notice shall be included in all
18
+ copies or substantial portions of the Software.
19
+
20
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
+ SOFTWARE.
27
+
28
+ Description-Content-Type: text/markdown
29
+ License-File: LICENSE
30
+ Requires-Dist: numpy
31
+ Requires-Dist: astropy
32
+ Requires-Dist: matplotlib
33
+ Requires-Dist: reproject
34
+ Requires-Dist: regions
35
+ Requires-Dist: scipy
36
+ Requires-Dist: photutils
37
+
38
+ [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.19393439.svg)](https://doi.org/10.5281/zenodo.19393439)
39
+
40
+ <img src="https://raw.githubusercontent.com/AndressaWille/lightstack/master/images/logo.png" width="120">
41
+
42
+ # Lightstack
43
+
44
+ Tools for building and processing multi-filter astrophysical datacubes.
45
+
46
+ ## Features
47
+
48
+ - Cropping FITS images
49
+ - Building photometric datacubes
50
+ - PSF matching
51
+
52
+ (Currently supports JWST and HST)
53
+
54
+ ## Installation
55
+
56
+ ```bash
57
+ pip install lightstack
58
+ ```
59
+
60
+ ## Documentation
61
+
62
+ https://lightstack.readthedocs.io/en/latest/
63
+
64
+ See the tutorial notebook!
@@ -0,0 +1,27 @@
1
+ [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.19393439.svg)](https://doi.org/10.5281/zenodo.19393439)
2
+
3
+ <img src="https://raw.githubusercontent.com/AndressaWille/lightstack/master/images/logo.png" width="120">
4
+
5
+ # Lightstack
6
+
7
+ Tools for building and processing multi-filter astrophysical datacubes.
8
+
9
+ ## Features
10
+
11
+ - Cropping FITS images
12
+ - Building photometric datacubes
13
+ - PSF matching
14
+
15
+ (Currently supports JWST and HST)
16
+
17
+ ## Installation
18
+
19
+ ```bash
20
+ pip install lightstack
21
+ ```
22
+
23
+ ## Documentation
24
+
25
+ https://lightstack.readthedocs.io/en/latest/
26
+
27
+ See the tutorial notebook!
@@ -1,7 +1,8 @@
1
1
  [project]
2
2
  name = "lightstack"
3
- version = "0.1.0"
3
+ version = "0.1.2"
4
4
  description = "Tools for building and processing multi-filter astrophysical datacubes"
5
+ readme = "README.md"
5
6
  authors = [{name = "Andressa Wille"}, {name="Thallis Pessi"}]
6
7
  dependencies = [
7
8
  "numpy",
@@ -6,7 +6,7 @@ from astropy.wcs import WCS
6
6
 
7
7
  from reproject import reproject_interp, reproject_exact
8
8
 
9
- from .utils import find_ext, infer_filter
9
+ from .utils import find_ext, infer_filter, get_pixel_scale_wcs
10
10
 
11
11
 
12
12
  def align_reproject_fits(fits_list, ref_file, method="interp", crop=1):
@@ -24,7 +24,7 @@ def align_reproject_fits(fits_list, ref_file, method="interp", crop=1):
24
24
  method : str, optional
25
25
  Reprojection method:
26
26
  - "interp" (default): faster, interpolates values
27
- - "exact": slower, conserves flux --> but reproject_exact has precision issues with resolutions below ~0.05 arcsec, so the results may not be accurate.
27
+ - "exact": slower --> but reproject_exact has precision issues with resolutions below ~0.05 arcsec, so the results may not be accurate.
28
28
 
29
29
  crop : int, optional
30
30
  Number of pixels to remove from each border after reprojection
@@ -36,6 +36,7 @@ def align_reproject_fits(fits_list, ref_file, method="interp", crop=1):
36
36
  List in the form [(aligned_fits_path, filter_name), ...].
37
37
  """
38
38
 
39
+
39
40
  # Choose reprojection method
40
41
  if method == "exact":
41
42
  reproj_func = reproject_exact
@@ -54,6 +55,9 @@ def align_reproject_fits(fits_list, ref_file, method="interp", crop=1):
54
55
  ref_wcs = WCS(ref_header)
55
56
  shape_out = hdul_ref[ext_ref].data.shape
56
57
 
58
+ # Pixel scale of reference
59
+ scale_out = get_pixel_scale_from_wcs(ref_wcs)
60
+
57
61
  aligned_list = []
58
62
 
59
63
  # Loop over all FITS
@@ -65,20 +69,30 @@ def align_reproject_fits(fits_list, ref_file, method="interp", crop=1):
65
69
  print(f"No data extension found in {fpath}. Skipping.")
66
70
  continue
67
71
 
68
- data = hdul[ext].data
72
+ data = hdul[ext].data.astype(float)
69
73
  header = hdul[ext].header
70
74
  wcs_in = WCS(header)
71
75
 
72
76
  unit = header.get('BUNIT', 'unknown')
73
77
  print(f"Filter {filt}: unit = {unit}")
74
78
 
79
+ # Pixel scale of input
80
+ scale_in = get_pixel_scale_from_wcs(wcs_in)
81
+
75
82
  # Reproject
76
83
  data_aligned, footprint = reproj_func(
77
84
  (data, wcs_in),
78
85
  ref_wcs,
79
86
  shape_out=shape_out)
80
87
 
81
- # Crop border (interp method)
88
+ # Area correction
89
+ area_ratio = (scale_out / scale_in)**2
90
+ data_aligned *= area_ratio
91
+
92
+ print(f"Pixel scale in/out: {scale_in:.4f} -> {scale_out:.4f}")
93
+ print(f"Applied area correction: {area_ratio:.4f}")
94
+
95
+ # Crop border
82
96
  if crop > 0:
83
97
  data_aligned = data_aligned[crop:-crop, crop:-crop]
84
98
 
@@ -90,10 +104,13 @@ def align_reproject_fits(fits_list, ref_file, method="interp", crop=1):
90
104
 
91
105
  # Header
92
106
  header_aligned = wcs_out.to_header()
107
+ header_aligned['BUNIT'] = unit
93
108
 
94
109
  ref_filter = infer_filter(ref_file)
95
110
  header_aligned.add_history(
96
111
  f"Reprojected to {ref_filter} using {method} method (reproject package)")
112
+ header_aligned.add_history(
113
+ "Flux corrected by pixel area ratio")
97
114
 
98
115
  if crop > 0:
99
116
  header_aligned.add_history(f"Cropped {crop} pixels from each border")
@@ -105,10 +122,16 @@ def align_reproject_fits(fits_list, ref_file, method="interp", crop=1):
105
122
  fits.PrimaryHDU(data_aligned, header=header_aligned).writeto(
106
123
  out_name, overwrite=True)
107
124
 
125
+ # Flux sanity check
126
+ sum_in = np.nansum(data)
127
+ sum_out = np.nansum(data_aligned)
128
+ print(f"Flux ratio (out/in): {sum_out/sum_in:.4f}")
129
+
108
130
  aligned_list.append((out_name, filt))
109
131
  print(f"Saved: {out_name}")
110
132
 
111
133
  return aligned_list
134
+
112
135
 
113
136
 
114
137
  def build_datacube(aligned_fits_files, reference_file, output_path):
@@ -125,8 +125,14 @@ def resample_psf(
125
125
  raise ValueError("Provide either zoom_factor OR both psf_pixel_scale and target_pixel_scale")
126
126
  zoom_factor = psf_pixel_scale / target_pixel_scale
127
127
 
128
+ if zoom_factor > 1:
129
+ raise ValueError("Upsampling not recommended.")
130
+
128
131
  # Resample
129
132
  psf_resampled = zoom(psf, zoom_factor, order=order)
133
+
134
+ # Area correction
135
+ psf_resampled /= zoom_factor**2
130
136
 
131
137
  # Ensure odd shape
132
138
  if make_odd_shape:
@@ -143,6 +149,7 @@ def resample_psf(
143
149
  header["HISTORY"] = "PSF resampled using scipy.ndimage.zoom"
144
150
  if target_pixel_scale is not None:
145
151
  header["CDELT1"] = (target_pixel_scale / 3600, "deg/pix")
152
+ header["CDELT2"] = (target_pixel_scale / 3600, "deg/pix")
146
153
 
147
154
  # Save
148
155
  fits.PrimaryHDU(psf_resampled, header=header).writeto(
@@ -210,7 +210,7 @@ def MJy_sr_to_jy(aligned_list):
210
210
 
211
211
  def get_pixel_scale(fits_path):
212
212
  """
213
- Compute pixel scale in arcsec/pixel using WCS.
213
+ Compute pixel scale in arcsec/pixel using WCS. Assumes square pixels and no significant distortion.
214
214
  """
215
215
  with fits.open(fits_path) as hdul:
216
216
  ext = find_ext(hdul)
@@ -221,3 +221,11 @@ def get_pixel_scale(fits_path):
221
221
 
222
222
  pixscale = proj_plane_pixel_scales(wcs)[0] * 3600.0
223
223
  return pixscale
224
+
225
+
226
+ def get_pixel_scale_from_wcs(wcs):
227
+ """
228
+ Compute pixel scale in arcsec/pixel from a WCS object.
229
+ Assumes square pixels and no significant distortion.
230
+ """
231
+ return proj_plane_pixel_scales(wcs)[0] * 3600.0
@@ -0,0 +1,64 @@
1
+ Metadata-Version: 2.1
2
+ Name: lightstack
3
+ Version: 0.1.2
4
+ Summary: Tools for building and processing multi-filter astrophysical datacubes
5
+ Author: Andressa Wille, Thallis Pessi
6
+ License: MIT License
7
+
8
+ Copyright (c) 2026 Andressa Wille, Thallis Pessi
9
+
10
+ Permission is hereby granted, free of charge, to any person obtaining a copy
11
+ of this software and associated documentation files (the "Software"), to deal
12
+ in the Software without restriction, including without limitation the rights
13
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
+ copies of the Software, and to permit persons to whom the Software is
15
+ furnished to do so, subject to the following conditions:
16
+
17
+ The above copyright notice and this permission notice shall be included in all
18
+ copies or substantial portions of the Software.
19
+
20
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
+ SOFTWARE.
27
+
28
+ Description-Content-Type: text/markdown
29
+ License-File: LICENSE
30
+ Requires-Dist: numpy
31
+ Requires-Dist: astropy
32
+ Requires-Dist: matplotlib
33
+ Requires-Dist: reproject
34
+ Requires-Dist: regions
35
+ Requires-Dist: scipy
36
+ Requires-Dist: photutils
37
+
38
+ [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.19393439.svg)](https://doi.org/10.5281/zenodo.19393439)
39
+
40
+ <img src="https://raw.githubusercontent.com/AndressaWille/lightstack/master/images/logo.png" width="120">
41
+
42
+ # Lightstack
43
+
44
+ Tools for building and processing multi-filter astrophysical datacubes.
45
+
46
+ ## Features
47
+
48
+ - Cropping FITS images
49
+ - Building photometric datacubes
50
+ - PSF matching
51
+
52
+ (Currently supports JWST and HST)
53
+
54
+ ## Installation
55
+
56
+ ```bash
57
+ pip install lightstack
58
+ ```
59
+
60
+ ## Documentation
61
+
62
+ https://lightstack.readthedocs.io/en/latest/
63
+
64
+ See the tutorial notebook!
@@ -1,3 +1,4 @@
1
+ LICENSE
1
2
  README.md
2
3
  pyproject.toml
3
4
  src/lightstack/__init__.py
lightstack-0.1.0/PKG-INFO DELETED
@@ -1,12 +0,0 @@
1
- Metadata-Version: 2.1
2
- Name: lightstack
3
- Version: 0.1.0
4
- Summary: Tools for building and processing multi-filter astrophysical datacubes
5
- Author: Andressa Wille, Thallis Pessi
6
- Requires-Dist: numpy
7
- Requires-Dist: astropy
8
- Requires-Dist: matplotlib
9
- Requires-Dist: reproject
10
- Requires-Dist: regions
11
- Requires-Dist: scipy
12
- Requires-Dist: photutils
@@ -1,18 +0,0 @@
1
- <img src="images/logo.png" width="120">
2
-
3
- # Lightstack
4
-
5
-
6
- This is a code with functions for:
7
- - cropping FITS images
8
- - building photometric datacubes
9
- - PSF matching
10
-
11
- (only JWST and HST for now)
12
-
13
- pip install git+https://github.com/AndressaWille/lightstack.git
14
-
15
-
16
- Documentation: https://lightstack.readthedocs.io/en/latest/
17
-
18
- See the tutorial notebook!
@@ -1,12 +0,0 @@
1
- Metadata-Version: 2.1
2
- Name: lightstack
3
- Version: 0.1.0
4
- Summary: Tools for building and processing multi-filter astrophysical datacubes
5
- Author: Andressa Wille, Thallis Pessi
6
- Requires-Dist: numpy
7
- Requires-Dist: astropy
8
- Requires-Dist: matplotlib
9
- Requires-Dist: reproject
10
- Requires-Dist: regions
11
- Requires-Dist: scipy
12
- Requires-Dist: photutils
File without changes