Coverage for python/lsst/cp/pipe/ptc/photodiode.py: 16%

40 statements  

« prev     ^ index     » next       coverage.py v7.2.1, created at 2023-03-12 11:11 +0000

1# This file is part of cp_pipe. 

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 COPYRIGHT file at the top-level directory of this distribution 

7# for details of code ownership. 

8# 

9# This program is free software: you can redistribute it and/or modify 

10# it under the terms of the GNU General Public License as published by 

11# the Free Software Foundation, either version 3 of the License, or 

12# (at your option) any later version. 

13# 

14# This program is distributed in the hope that it will be useful, 

15# but WITHOUT ANY WARRANTY; without even the implied warranty of 

16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 

17# GNU General Public License for more details. 

18# 

19# You should have received a copy of the GNU General Public License 

20# along with this program. If not, see <http://www.gnu.org/licenses/>. 

21 

22__all__ = ('PhotodiodeData', 'getBOTphotodiodeData') 

23 

24import os 

25import numpy as np 

26 

27import lsst.log as lsstLog 

28 

29 

30def getBOTphotodiodeData(dataRef, dataPath='/project/shared/BOT/_parent/raw/photodiode_data/', 

31 logger=None): 

32 """Get the photodiode data associated with a BOT dataRef. 

33 

34 This is a temporary Gen2-only interface to the photodiode readings from 

35 the SLAC Run3 datasets onwards. 

36 

37 Parameters 

38 ---------- 

39 dataRef : `lsst.daf.persistence.ButlerDataRef` 

40 dataRef of the of the detector/visit to load the data for. 

41 

42 dataPath : `str`, optional 

43 Path at which to find the corresponding photodiode data files. 

44 

45 logger : `lsst.log.Log`, optional 

46 Logger for logging warnings. 

47 

48 

49 Returns 

50 ------- 

51 photodiodeData : `lsst.cp.pipe.photodiode.PhotodiodeData` or `None` 

52 The full time-series of the photodiode readings, with methods to 

53 integrate the photocharge, or None if the expected file isn't found. 

54 """ 

55 if logger is None: 

56 logger = lsstLog.Log.getDefaultLogger() 

57 

58 def getKeyFromDataId(dataRef, key): 

59 if key in dataRef.dataId: 

60 return dataRef.dataId[key] 

61 else: 

62 result = dataRef.getButler().queryMetadata('raw', key, dataRef.dataId) 

63 assert len(result) == 1, f"Failed to find unique value for {key} with {dataRef.dataId}" 

64 return result[0] 

65 

66 dayObs = getKeyFromDataId(dataRef, 'dayObs') 

67 seqNum = getKeyFromDataId(dataRef, 'seqNum') 

68 

69 filePattern = 'Photodiode_Readings_%s_%06d.txt' 

70 

71 dayObsAsNumber = dayObs.replace('-', '') 

72 diodeFilename = os.path.join(dataPath, filePattern % (dayObsAsNumber, seqNum)) 

73 

74 if not os.path.exists(diodeFilename): 

75 logger.warn(f"Failed to find the photodiode data at {diodeFilename}") 

76 return None 

77 

78 try: 

79 photodiodeData = PhotodiodeData(diodeFilename) 

80 return photodiodeData 

81 except Exception: 

82 logger.warn(f"Photodiode data found at {diodeFilename} but failed to load.") 

83 return None 

84 

85 

86class PhotodiodeData(): 

87 def __init__(self, filename): 

88 self.times, self.values = np.loadtxt(filename, unpack=True) 

89 return 

90 

91 def getCharge(self, subtractBaseline=False): 

92 if subtractBaseline: 

93 raise NotImplementedError 

94 

95 charge = 0 

96 for i, (time, current) in enumerate(zip(self.times[:-1], self.values[:-1])): 

97 timestep = self.times[i+1] - time 

98 averageCurrent = (self.values[i+1] + current) / 2. 

99 charge += averageCurrent * timestep 

100 return charge