CelestialSurveyor
163 строки · 6.0 Кб
1import numpy as np2
3from astropy.coordinates import SkyCoord4from astropy.wcs import WCS5from dataclasses import dataclass6from datetime import datetime7from decimal import Decimal8from typing import Optional9
10
11@dataclass
12class SolveData:13"""14Class representing data required for plate solving of an image which is present in FITS or XISF header.
15
16Attributes:
17sky_coord (SkyCoord): The sky coordinates of image center.
18pixel_scale (Decimal): The pixel scale.
19"""
20sky_coord: SkyCoord21pixel_scale: Decimal22
23def __post_init__(self):24"""25Ensure the pixel scale is of Decimal type.
26"""
27if not isinstance(self.pixel_scale, Decimal):28raise TypeError("Pixel scale must be a Decimal object.")29if not isinstance(self.sky_coord, SkyCoord):30raise TypeError("Sky coordinates must be a SkyCoord object.")31
32def __repr__(self):33return f"SolveData(sky_coord={self.sky_coord}, pixel_scale={self.pixel_scale})"34
35def __str__(self):36return f"SolveData: Sky Coordinate: {self.sky_coord}, Pixel Scale: {self.pixel_scale}"37
38
39@dataclass
40class SiteLocation:41"""42Class to represent a site's geographical location.
43
44Attributes:
45lat (Decimal): The latitude of the site in decimal degrees.
46long (Decimal): The longitude of the site in decimal degrees.
47"""
48lat: Decimal49long: Decimal50
51def __post_init__(self):52"""53Ensure the lat and long are of Decimal type.
54"""
55if not isinstance(self.lat, Decimal):56raise TypeError("Latitude must be a Decimal object.")57if not isinstance(self.long, Decimal):58raise TypeError("Longitude must be a Decimal object.")59
60def __repr__(self):61return f"SiteLocation(lat={self.lat}, long={self.long})"62
63def __str__(self):64return f"SiteLocation: Latitude: {self.lat}, Longitude: {self.long}"65
66
67@dataclass
68class Header:69"""70Class to represent the header information of an image.
71
72Attributes:
73file_name (str): The name of the image file.
74exposure (Decimal): The exposure time of the image.
75timestamp (datetime): The timestamp of the image.
76site_location (SiteLocation): The geographical location of the site.
77solve_data (SolveData) [Optional]: The data required for plate solving of the image.
78wcs (WCS) [Optional]: WCS data - plate solve result.
79"""
80file_name: str81exposure: Decimal82timestamp: datetime83site_location: SiteLocation84solve_data: Optional[SolveData] = None85wcs: Optional[WCS] = None86
87def __post_init__(self):88"""89Perform type-checking on the attributes of the Header class to ensure correct data types.
90"""
91if not isinstance(self.file_name, str):92raise TypeError("File name must be a string.")93
94if not isinstance(self.exposure, Decimal):95raise TypeError("Exposure must be a Decimal object.")96
97if not isinstance(self.timestamp, datetime):98raise TypeError("Timestamp must be a datetime.datetime object.")99
100if not isinstance(self.exposure, Decimal):101raise TypeError("Exposure must be a Decimal object.")102
103if not isinstance(self.site_location, SiteLocation):104raise TypeError("Site location must be a SiteLocation object.")105
106if not isinstance(self.solve_data, SolveData) and self.solve_data is not None:107raise TypeError("Solve data must be a SolveData object or None.")108
109if not isinstance(self.wcs, WCS) and self.wcs is not None:110raise TypeError("WCS data must be a WCS object or None.")111
112def __repr__(self):113return (f"Header(file_name={self.file_name}, exposure={self.exposure}, timestamp={self.timestamp}, "114f"site_location={self.site_location}, solve_data={self.solve_data}, wcs={self.wcs})")115
116def __str__(self):117return (f"Header: File Name: {self.file_name}, Exposure: {self.exposure}, Timestamp: {self.timestamp}, "118f"Site Location: {self.site_location}, Solve Data: {self.solve_data}, WCS: {self.wcs}")119
120
121@dataclass
122class SharedMemoryParams:123"""124Data class representing parameters for shared memory file.
125Shared memory file is used to spread image data across multiple processes.
126
127Attributes:
128shm_name (str): The name of the shared memory.
129shm_size (int): The size of the shared memory.
130shm_shape (Tuple): The shape of the shared memory.
131shm_dtype (np.dtype): The data type of the shared memory.
132y_slice (slice): The y slice of the original image. Defaults to slice(None, None).
133x_slice (slice): The x slice of the original image. Defaults to slice(None, None).
134"""
135shm_name: str136shm_size: int137shm_shape: tuple138shm_dtype: np.dtype139y_slice: slice = slice(None, None)140x_slice: slice = slice(None, None)141
142def __post_init__(self):143if not isinstance(self.shm_name, str):144raise TypeError("Shared memory name must be a string.")145if not isinstance(self.shm_size, int):146raise TypeError("Shared memory size must be an integer.")147if not isinstance(self.shm_shape, tuple):148raise TypeError("Shared memory shape must be a tuple.")149if not isinstance(self.y_slice, slice):150raise TypeError("Y slice must be a slice.")151if not isinstance(self.x_slice, slice):152raise TypeError("X slice must be a slice.")153
154
155
156def __repr__(self):157return (f"SharedMemoryParams(shm_name={self.shm_name}, shm_size={self.shm_size}, shm_shape={self.shm_shape}, "158f"shm_dtype={self.shm_dtype}, y_slice={self.y_slice}, x_slice={self.x_slice})")159
160def __str__(self):161return (f"SharedMemoryParams: Shared Memory Name: {self.shm_name}, Shared Memory Size: {self.shm_size}, "162f"Shared Memory Shape: {self.shm_shape}, Shared Memory Data Type: {self.shm_dtype}, "163f"Y Slice: {self.y_slice}, X Slice: {self.x_slice}")164