Coverage for python/astro_metadata_translator/serialize/fits.py: 15%

36 statements  

« prev     ^ index     » next       coverage.py v7.4.4, created at 2024-04-06 03:48 -0700

1# This file is part of astro_metadata_translator. 

2# 

3# Developed for the LSST Data Management System. 

4# This product includes software developed by the LSST Project 

5# (http://www.lsst.org). 

6# See the LICENSE file at the top-level directory of this distribution 

7# for details of code ownership. 

8# 

9# Use of this source code is governed by a 3-clause BSD-style 

10# license that can be found in the LICENSE file. 

11 

12"""Transform ObservationInfo into "standard" FITS headers.""" 

13from __future__ import annotations 

14 

15__all__ = ("info_to_fits", "dates_to_fits", "group_to_fits") 

16 

17from typing import TYPE_CHECKING, Any 

18 

19if TYPE_CHECKING: 

20 import astropy.time 

21 

22 from ..observationGroup import ObservationGroup 

23 from ..observationInfo import ObservationInfo 

24 

25 

26def dates_to_fits(date_begin: astropy.time.Time, date_end: astropy.time.Time) -> dict[str, Any]: 

27 """Convert two dates into FITS form. 

28 

29 Parameters 

30 ---------- 

31 date_begin : `astropy.time.Time` 

32 Date representing the beginning of the observation. 

33 date_end : `astropy.time.Time` 

34 Date representing the end of the observation. 

35 

36 Returns 

37 ------- 

38 cards : `dict` of `str` to `str` or `float` 

39 Header card keys and values following the FITS standard. 

40 If neither date is defined this may be empty. 

41 """ 

42 cards: dict[str, Any] = {} 

43 if date_begin is None and date_end is None: 

44 # no date headers can be written 

45 return cards 

46 

47 cards["TIMESYS"] = "TAI" 

48 

49 date_avg = None 

50 if date_begin is not None and date_end is not None: 

51 date_avg = date_begin + (date_end - date_begin) / 2.0 

52 

53 for fragment, date in (("OBS", date_begin), ("BEG", date_begin), ("END", date_end), ("AVG", date_avg)): 

54 if date is not None: 

55 tai = date.tai 

56 cards[f"DATE-{fragment}"] = tai.isot 

57 cards[f"MJD-{fragment}"] = tai.mjd 

58 

59 return cards 

60 

61 

62def info_to_fits(obs_info: ObservationInfo) -> tuple[dict[str, Any], dict[str, str]]: 

63 """Convert an `ObservationInfo` to something suitable for writing 

64 to a FITS file. 

65 

66 Parameters 

67 ---------- 

68 obs_info : `ObservationInfo` 

69 Standardized observation information to transform to FITS headers. 

70 

71 Returns 

72 ------- 

73 cards : `dict` of `str` to (`int`, `float`, `str`, `bool`) 

74 FITS header keys and values in form understood by FITS. 

75 comments : `dict` of `str` to `str` 

76 Suitable comment string. There will be at most one entry for each key 

77 in ``cards``. 

78 """ 

79 cards = {} 

80 comments = {} 

81 

82 if obs_info.instrument is not None: 

83 cards["INSTRUME"] = obs_info.instrument 

84 comments["INSTRUME"] = "Name of instrument" 

85 

86 cards.update(dates_to_fits(obs_info.datetime_begin, obs_info.datetime_end)) 

87 

88 return cards, comments 

89 

90 

91def group_to_fits(obs_group: ObservationGroup) -> tuple[dict[str, Any], dict[str, str]]: 

92 """Convert an `ObservationGroup` to something suitable for writing 

93 to a FITS file. 

94 

95 Parameters 

96 ---------- 

97 obs_group : `ObservationGroup` 

98 Collection of observation information to transform to a single 

99 FITS header. 

100 

101 Returns 

102 ------- 

103 cards : `dict` of `str` to (`int`, `float`, `str`, `bool`) 

104 FITS header keys and values in form understood by FITS. 

105 comments : `dict` of `str` to `str` 

106 Suitable comment string. There will be at most one entry for each key 

107 in ``cards``. 

108 """ 

109 cards = {} 

110 comments = {} 

111 

112 oldest, newest = obs_group.extremes() 

113 

114 instruments = obs_group.property_values("instrument") 

115 if len(instruments) == 1: 

116 cards["INSTRUME"] = list(instruments)[0] 

117 comments["INSTRUME"] = "Name of instrument" 

118 

119 cards.update(dates_to_fits(oldest.datetime_begin, newest.datetime_end)) 

120 

121 return cards, comments