lvm-tools 0.0.2.dev0__tar.gz → 0.0.4__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.
Files changed (27) hide show
  1. {lvm_tools-0.0.2.dev0 → lvm_tools-0.0.4}/PKG-INFO +24 -2
  2. {lvm_tools-0.0.2.dev0 → lvm_tools-0.0.4}/README.md +21 -1
  3. {lvm_tools-0.0.2.dev0 → lvm_tools-0.0.4}/pyproject.toml +3 -3
  4. {lvm_tools-0.0.2.dev0 → lvm_tools-0.0.4}/src/lvm_tools/_version.py +2 -2
  5. lvm_tools-0.0.4/src/lvm_tools/data/coordinates.py +33 -0
  6. {lvm_tools-0.0.2.dev0 → lvm_tools-0.0.4}/src/lvm_tools/fit_data/fit_data.py +21 -2
  7. lvm_tools-0.0.2.dev0/src/lvm_tools/data/coordinates.py +0 -73
  8. {lvm_tools-0.0.2.dev0 → lvm_tools-0.0.4}/.gitignore +0 -0
  9. {lvm_tools-0.0.2.dev0 → lvm_tools-0.0.4}/LICENSE +0 -0
  10. {lvm_tools-0.0.2.dev0 → lvm_tools-0.0.4}/src/lvm_tools/__init__.py +0 -0
  11. {lvm_tools-0.0.2.dev0 → lvm_tools-0.0.4}/src/lvm_tools/config/__init__.py +0 -0
  12. {lvm_tools-0.0.2.dev0 → lvm_tools-0.0.4}/src/lvm_tools/config/data_config.py +0 -0
  13. {lvm_tools-0.0.2.dev0 → lvm_tools-0.0.4}/src/lvm_tools/config/validation.py +0 -0
  14. {lvm_tools-0.0.2.dev0 → lvm_tools-0.0.4}/src/lvm_tools/data/__init__.py +0 -0
  15. {lvm_tools-0.0.2.dev0 → lvm_tools-0.0.4}/src/lvm_tools/data/helper.py +0 -0
  16. {lvm_tools-0.0.2.dev0 → lvm_tools-0.0.4}/src/lvm_tools/data/tile.py +0 -0
  17. {lvm_tools-0.0.2.dev0 → lvm_tools-0.0.4}/src/lvm_tools/fit_data/__init__.py +0 -0
  18. {lvm_tools-0.0.2.dev0 → lvm_tools-0.0.4}/src/lvm_tools/fit_data/builder.py +0 -0
  19. {lvm_tools-0.0.2.dev0 → lvm_tools-0.0.4}/src/lvm_tools/fit_data/clipping.py +0 -0
  20. {lvm_tools-0.0.2.dev0 → lvm_tools-0.0.4}/src/lvm_tools/fit_data/filtering.py +0 -0
  21. {lvm_tools-0.0.2.dev0 → lvm_tools-0.0.4}/src/lvm_tools/fit_data/normalisation.py +0 -0
  22. {lvm_tools-0.0.2.dev0 → lvm_tools-0.0.4}/src/lvm_tools/fit_data/processing.py +0 -0
  23. {lvm_tools-0.0.2.dev0 → lvm_tools-0.0.4}/src/lvm_tools/physical_properties/__init__.py +0 -0
  24. {lvm_tools-0.0.2.dev0 → lvm_tools-0.0.4}/src/lvm_tools/physical_properties/barycentric_corr.py +0 -0
  25. {lvm_tools-0.0.2.dev0 → lvm_tools-0.0.4}/src/lvm_tools/py.typed +0 -0
  26. {lvm_tools-0.0.2.dev0 → lvm_tools-0.0.4}/src/lvm_tools/utils/__init__.py +0 -0
  27. {lvm_tools-0.0.2.dev0 → lvm_tools-0.0.4}/src/lvm_tools/utils/mask.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: lvm_tools
3
- Version: 0.0.2.dev0
3
+ Version: 0.0.4
4
4
  Summary: Lazily read/encapsulate LVM DRP data in a modular way
5
5
  Author-email: Tom Hilder <Thomas.Hilder@monash.edu>
6
6
  License-File: LICENSE
@@ -10,6 +10,8 @@ Requires-Dist: dask>=2025.7.0
10
10
  Requires-Dist: numpy>=2.3.2
11
11
  Requires-Dist: scipy>=1.16.1
12
12
  Requires-Dist: xarray>=2025.7.1
13
+ Provides-Extra: spectracles
14
+ Requires-Dist: spectracles>=0.5.1; extra == 'spectracles'
13
15
  Description-Content-Type: text/markdown
14
16
 
15
17
  # lvm_tools
@@ -20,7 +22,25 @@ Feel free to contact me personally if you have any questions at all.
20
22
 
21
23
  ## Installation
22
24
 
23
- TODO
25
+ Easiest is from PyPI either with `pip`
26
+
27
+ ```sh
28
+ pip install lvm-tools
29
+ ```
30
+
31
+ or `uv` (recommended)
32
+
33
+ ```sh
34
+ uv add lvm-tools
35
+ ```
36
+
37
+ Or, you can clone and build from source
38
+
39
+ ```sh
40
+ git clone git@github.com:TomHilder/lvm_tools.git
41
+ cd lvm_tools
42
+ pip install -e .
43
+ ```
24
44
 
25
45
  ## Usage
26
46
 
@@ -36,7 +56,9 @@ TODO
36
56
 
37
57
  ## TODO
38
58
 
59
+ - [ ] Relax version requirements from being strictly my environment (which is very up-to-date)
39
60
  - [ ] repr for FitData
40
61
  - [ ] Logging/hashing
41
62
  - [ ] Cache
42
63
  - [ ] OptConfig
64
+ - [ ] Testing ?
@@ -6,7 +6,25 @@ Feel free to contact me personally if you have any questions at all.
6
6
 
7
7
  ## Installation
8
8
 
9
- TODO
9
+ Easiest is from PyPI either with `pip`
10
+
11
+ ```sh
12
+ pip install lvm-tools
13
+ ```
14
+
15
+ or `uv` (recommended)
16
+
17
+ ```sh
18
+ uv add lvm-tools
19
+ ```
20
+
21
+ Or, you can clone and build from source
22
+
23
+ ```sh
24
+ git clone git@github.com:TomHilder/lvm_tools.git
25
+ cd lvm_tools
26
+ pip install -e .
27
+ ```
10
28
 
11
29
  ## Usage
12
30
 
@@ -22,7 +40,9 @@ TODO
22
40
 
23
41
  ## TODO
24
42
 
43
+ - [ ] Relax version requirements from being strictly my environment (which is very up-to-date)
25
44
  - [ ] repr for FitData
26
45
  - [ ] Logging/hashing
27
46
  - [ ] Cache
28
47
  - [ ] OptConfig
48
+ - [ ] Testing ?
@@ -13,6 +13,9 @@ dependencies = [
13
13
  "xarray>=2025.7.1",
14
14
  ]
15
15
 
16
+ [project.optional-dependencies]
17
+ spectracles = ["spectracles>=0.5.1"]
18
+
16
19
  [build-system]
17
20
  requires = ["hatchling", "hatch-vcs"]
18
21
  build-backend = "hatchling.build"
@@ -33,8 +36,5 @@ version-file = "src/lvm_tools/_version.py"
33
36
  [tool.hatch.version]
34
37
  source = "vcs"
35
38
 
36
- [tool.hatch.version.raw-options]
37
- local_scheme = "no-local-version"
38
-
39
39
  [tool.ruff]
40
40
  line-length = 99 # Sorry PEP8 I'm a rebel
@@ -17,5 +17,5 @@ __version__: str
17
17
  __version_tuple__: VERSION_TUPLE
18
18
  version_tuple: VERSION_TUPLE
19
19
 
20
- __version__ = version = '0.0.2.dev0'
21
- __version_tuple__ = version_tuple = (0, 0, 2, 'dev0')
20
+ __version__ = version = '0.0.4'
21
+ __version_tuple__ = version_tuple = (0, 0, 4)
@@ -0,0 +1,33 @@
1
+ """coordinates.py - observation time and location extraction for LVM data processing."""
2
+
3
+ from astropy.coordinates import EarthLocation
4
+ from astropy.io.fits import Header
5
+ from astropy.time import Time
6
+
7
+
8
+ def get_mjd(header: Header) -> float:
9
+ if "INTSTART" in header and "INTEND" in header:
10
+ start_time = Time(header["INTSTART"], format="isot")
11
+ end_time = Time(header["INTEND"], format="isot")
12
+ mid_time = start_time + (end_time - start_time) / 2
13
+ return mid_time.mjd
14
+ else:
15
+ raise ValueError("Could not find sufficient time information in header")
16
+
17
+
18
+ def get_observatory_code(header: Header) -> str:
19
+ observatory = header.get("OBSERVAT", "").strip()
20
+ known_observatories = ["LCO"]
21
+ if observatory in known_observatories:
22
+ return observatory
23
+ else:
24
+ raise ValueError(
25
+ f"Unknown observatory: {observatory}. Known observatories: {known_observatories}"
26
+ )
27
+
28
+
29
+ def get_observatory_location(observatory: str) -> EarthLocation:
30
+ if observatory == "LCO":
31
+ return EarthLocation.of_site("Las Campanas Observatory")
32
+ else:
33
+ raise ValueError(f"Unknown observatory: {observatory}")
@@ -4,17 +4,36 @@ from __future__ import annotations
4
4
 
5
5
  import warnings
6
6
  from dataclasses import dataclass
7
- from typing import Callable
7
+ from typing import TYPE_CHECKING, Callable
8
8
 
9
9
  import jax.numpy as jnp
10
10
  import numpy as np
11
11
  from jax.numpy import pi as π
12
12
  from jaxtyping import Array as JaxArray
13
- from modelling_lib.model.data import SpatialDataLVM
14
13
  from xarray import DataArray, Dataset
15
14
 
16
15
  from lvm_tools.physical_properties.barycentric_corr import get_v_barycentric
17
16
 
17
+ if TYPE_CHECKING:
18
+ from spectracles.model.data import SpatialDataLVM
19
+
20
+ try:
21
+ from spectracles.model.data import SpatialDataLVM
22
+ except Exception as e:
23
+ _import_err = e
24
+ msg = (
25
+ "Could not import SpatialDataLVM from spectracles.model.data. "
26
+ "Install the optional dependency: pip install spectracles"
27
+ )
28
+
29
+ class SpatialDataLVM: # stub preserves the API shape
30
+ def __init__(self, *args, **kwargs):
31
+ raise ModuleNotFoundError(msg) from _import_err
32
+
33
+ import warnings
34
+
35
+ warnings.warn(msg, ImportWarning)
36
+
18
37
 
19
38
  def to_π_domain(x):
20
39
  # return x * 2 * π - π
@@ -1,73 +0,0 @@
1
- """coordinates.py - observation time and location extraction for LVM data processing."""
2
-
3
- # NOTE: Code is generated by an LLM and may not be fully robust.
4
-
5
- import astropy.units as u
6
- from astropy.coordinates import EarthLocation
7
- from astropy.io.fits import Header
8
- from astropy.time import Time
9
-
10
-
11
- def get_mjd(header: Header) -> float:
12
- # Method 1: Use INTSTART and INTEND if available (most precise)
13
- if "INTSTART" in header and "INTEND" in header:
14
- start_time = Time(header["INTSTART"], format="isot")
15
- end_time = Time(header["INTEND"], format="isot")
16
- mid_time = start_time + (end_time - start_time) / 2
17
- # print(header["MJD"])
18
- # mid_time = Time(header["MJD"], format="mjd")
19
- # print(mid_time.mjd)
20
- # print()
21
-
22
- # Validation: check against header EXPTIME
23
- # calculated_exptime = (end_time - start_time).to(u.second).value
24
- # header_exptime = header.get("EXPTIME", 0.0)
25
- # if abs(calculated_exptime - header_exptime) > 1.0: # Allow 1s tolerance
26
- # print(
27
- # f" WARNING: Calculated exptime ({calculated_exptime:.1f}s) differs from header EXPTIME ({header_exptime}s)"
28
- # )
29
-
30
- return mid_time.mjd
31
-
32
- # # Method 2: Use OBSTIME + EXPTIME/2 as fallback
33
- # elif "OBSTIME" in header and "EXPTIME" in header:
34
- # start_time = Time(header["OBSTIME"], format="isot")
35
- # exptime = header["EXPTIME"] * u.second
36
- # mid_time = start_time + exptime / 2
37
-
38
- # return mid_time.mjd
39
-
40
- # # Method 3: Use header MJD + EXPTIME/2 (least precise, integer MJD)
41
- # elif "MJD" in header and "EXPTIME" in header:
42
- # mjd_start = header["MJD"] # This appears to be integer MJD
43
- # exptime_days = header["EXPTIME"] / 86400.0 # Convert seconds to days
44
- # mjd_mid = mjd_start + exptime_days / 2
45
-
46
- # return mjd_mid
47
-
48
- else:
49
- raise ValueError("Could not find sufficient time information in header")
50
-
51
-
52
- def get_observatory_code(header: Header) -> str:
53
- observatory = header.get("OBSERVAT", "").strip()
54
-
55
- # Just return the observatory code string
56
- # You can convert to EarthLocation later when needed
57
- known_observatories = ["LCO"] # Add other LVM observatory codes as needed
58
-
59
- if observatory in known_observatories:
60
- return observatory
61
- else:
62
- raise ValueError(
63
- f"Unknown observatory: {observatory}. Known observatories: {known_observatories}"
64
- )
65
-
66
-
67
- def get_observatory_location(observatory: str) -> EarthLocation:
68
- # LCO = Las Campanas Observatory
69
- if observatory == "LCO":
70
- return EarthLocation.of_site("Las Campanas Observatory")
71
- else:
72
- # Add other observatories as needed
73
- raise ValueError(f"Unknown observatory: {observatory}")
File without changes
File without changes