Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

# This file is currently part of obs_lsst but is written to allow it 

# to be migrated to the astro_metadata_translator package at a later date. 

# 

# This product includes software developed by the LSST Project 

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

# See the LICENSE file in this directory for details of code ownership. 

# 

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

# license that can be found in the LICENSE file. 

 

"""Metadata translation support code for LSST headers""" 

 

__all__ = ("ROLLOVERTIME", "TZERO", "LSST_LOCATION", "read_detector_ids", 

"compute_detector_exposure_id_generic") 

 

import os.path 

import yaml 

 

from astropy.time import Time, TimeDelta 

from astropy.coordinates import EarthLocation 

 

from lsst.utils import getPackageDir 

 

# LSST day clock starts at UTC+8 

ROLLOVERTIME = TimeDelta(8*60*60, scale="tai", format="sec") 

TZERO = Time("2010-01-01T00:00", format="isot", scale="utc") 

 

# LSST Default location in the absence of headers 

LSST_LOCATION = EarthLocation.from_geodetic(-30.244639, -70.749417, 2663.0) 

 

obs_lsst_packageDir = getPackageDir("obs_lsst") 

 

 

def read_detector_ids(policyFile): 

"""Read a camera policy file and retrieve the mapping from CCD name 

to ID. 

 

Parameters 

---------- 

policyFile : `str` 

Name of YAML policy file to read, relative to the obs_lsst 

package. 

 

Returns 

------- 

mapping : `dict` of `str` to (`int`, `str`) 

A `dict` with keys being the full names of the detectors, and the 

value is a `tuple` containing the integer detector number and the 

detector serial number. 

 

Notes 

----- 

Reads the camera YAML definition file directly and extracts just the 

IDs and serials. This routine does not use the standard 

`~lsst.obs.base.yamlCamera.YAMLCamera` infrastructure or 

`lsst.afw.cameraGeom`. This is because the translators are intended to 

have minimal dependencies on LSST infrastructure. 

""" 

 

file = os.path.join(obs_lsst_packageDir, policyFile) 

with open(file) as fh: 

# Use the fast parser since these files are large 

camera = yaml.load(fh, Loader=yaml.CLoader) 

 

mapping = {} 

for ccd, value in camera["CCDs"].items(): 

mapping[ccd] = (int(value["id"]), value["serial"]) 

 

return mapping 

 

 

def compute_detector_exposure_id_generic(exposure_id, detector_num, max_num=1000, mode="concat"): 

"""Compute the detector_exposure_id from the exposure id and the 

detector number. 

 

Parameters 

---------- 

exposure_id : `int` 

The exposure ID. 

detector_num : `int` 

The detector number. 

max_num : `int`, optional 

Maximum number of detectors to make space for. Defaults to 1000. 

mode : `str`, optional 

Computation mode. Defaults to "concat". 

- concat : Concatenate the exposure ID and detector number, making 

sure that there is space for max_num and zero padding. 

- multiply : Multiply the exposure ID by the maximum detector 

number and add the detector number. 

 

Returns 

------- 

detector_exposure_id : `int` 

Computed ID. 

 

Raises 

------ 

ValueError 

The detector number is out of range. 

""" 

 

if detector_num is None: 

raise ValueError("Detector number must be defined.") 

if detector_num >= max_num or detector_num < 0: 

raise ValueError(f"Detector number out of range 0 <= {detector_num} <= {max_num}") 

 

if mode == "concat": 

npad = len(str(max_num)) 

return int(f"{exposure_id}{detector_num:0{npad}d}") 

elif mode == "multiply": 

return max_num*exposure_id + detector_num 

else: 

raise ValueError(f"Computation mode of '{mode}' is not understood")