Coverage for pymarsseason/pymarsseason.py: 98%

46 statements  

« prev     ^ index     » next       coverage.py v7.10.7, created at 2025-09-23 10:46 +0000

1# PyMarsSeason - Computes the season based on the solar longitude 

2# Copyright (C) 2022-2025 - CNES (Jean-Christophe Malapert for PDSSP (Pôle de Données et Services Surfaces Planétaires)) 

3# This file is part of PyMarsSeason <https://github.com/pdssp/pymarsseason> 

4# SPDX-License-Identifier: Apache-2.0 

5"""This module contains the library.""" 

6from enum import Enum 

7from typing import Dict 

8from typing import Union 

9 

10from astropy.time import Time 

11from loguru import logger 

12 

13from ._version import __name_soft__ 

14from .config import configure_logging 

15from .marstime import Mars_Ls 

16 

17 

18class NoValue(Enum): 

19 def __repr__(self): 

20 return "<{}.{}>".format(self.__class__.__name__, self.name) 

21 

22 

23class Season(NoValue): 

24 SPRING = "spring" 

25 SUMMER = "summer" 

26 AUTUMN = "autumn" 

27 WINTER = "winter" 

28 

29 

30class Hemisphere(NoValue): 

31 NORTH = "north" 

32 SOUTH = "south" 

33 

34 

35class PyMarsSeason: 

36 """The library""" 

37 

38 def __init__(self, *args, **kwargs): 

39 # pylint: disable=unused-argument 

40 level = kwargs.get("level", "INFO") 

41 configure_logging(level=level) 

42 

43 def convert_ls_to_season( 

44 self, lsmars: float 

45 ) -> Dict[Union[Hemisphere, str], Union[Season, float]]: 

46 """Convert the areocentric longitude of Mars (Ls) to season. 

47 

48 Args: 

49 lsmars (float): Solar longitude 

50 

51 Raises: 

52 ValueError: Solar longitude must be in [0, 360[ 

53 

54 Returns: 

55 Dict[Union[Hemisphere, str], Union[Season, float]]: Return the season name for each hemisphere and the solar longitude 

56 """ 

57 result: Dict[Union[Hemisphere, str], Union[Season, float]] = dict() 

58 if 0 <= lsmars < 90: 

59 result = { 

60 Hemisphere.NORTH: Season.SPRING, 

61 Hemisphere.SOUTH: Season.AUTUMN, 

62 } 

63 elif 90 <= lsmars < 180: 

64 result = { 

65 Hemisphere.NORTH: Season.SUMMER, 

66 Hemisphere.SOUTH: Season.WINTER, 

67 } 

68 elif 180 <= lsmars < 270: 

69 result = { 

70 Hemisphere.NORTH: Season.AUTUMN, 

71 Hemisphere.SOUTH: Season.SPRING, 

72 } 

73 elif 270 <= lsmars < 360: 

74 result = { 

75 Hemisphere.NORTH: Season.WINTER, 

76 Hemisphere.SOUTH: Season.SUMMER, 

77 } 

78 else: 

79 raise ValueError("Solar longitude must be in [0, 360[") 

80 

81 result["ls"] = lsmars 

82 return result 

83 

84 def compute_season_from_time( 

85 self, time: Time 

86 ) -> Dict[Union[Hemisphere, str], Union[Season, float]]: 

87 """Compute the season from time. 

88 

89 Args: 

90 time (Time): TT scale with ISO format 

91 

92 Raises: 

93 ValueError: Solar longitude must be in [0, 360[ 

94 

95 Returns: 

96 Dict[Union[Hemisphere, str], Union[Season, float]]: Return the season name for each hemisphere and the solar longitude 

97 """ 

98 logger.debug(f"Input: {time}") 

99 assert isinstance( 

100 time, Time 

101 ), "time must have the astropy.time.Time type" 

102 assert time.scale == "utc", "Time must be in terrestrial time scale" 

103 

104 # convert to J2000 

105 deltJ2000 = time.jd - 2451545.0 

106 

107 lsmars = float(Mars_Ls(deltJ2000)) 

108 logger.debug(f"Solar longitude: {lsmars}") 

109 

110 season: Dict[Union[Hemisphere, str], Union[Season, float]] = ( 

111 self.convert_ls_to_season(lsmars) 

112 ) 

113 logger.debug(f"Season in Mars in {time} = {season}") 

114 return season