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

40 statements  

« prev     ^ index     » next       coverage.py v6.4.1, created at 2022-07-09 05:55 -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, Dict, Tuple 

18 

19if TYPE_CHECKING: 19 ↛ 20line 19 didn't jump to line 20, because the condition on line 19 was never true

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), ("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 

80 cards = {} 

81 comments = {} 

82 

83 if obs_info.instrument is not None: 

84 cards["INSTRUME"] = obs_info.instrument 

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

86 

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

88 

89 return cards, comments 

90 

91 

92def group_to_fits(obs_group: ObservationGroup) -> Tuple[Dict[str, Any], Dict[str, str]]: 

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

94 to a FITS file. 

95 

96 Parameters 

97 ---------- 

98 obs_group : `ObservationGroup` 

99 Collection of observation information to transform to a single 

100 FITS header. 

101 

102 Returns 

103 ------- 

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

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

106 comments : `dict` of `str` to `str` 

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

108 in ``cards``. 

109 """ 

110 

111 cards = {} 

112 comments = {} 

113 

114 oldest, newest = obs_group.extremes() 

115 

116 instruments = obs_group.property_values("instrument") 

117 if len(instruments) == 1: 

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

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

120 

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

122 

123 return cards, comments