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

1from builtins import zip 

2import numpy as np 

3from .baseMetric import BaseMetric 

4from lsst.sims.utils import Site 

5 

6__all__ = ['HourglassMetric'] 

7 

8 

9def nearestVal(A, val): 

10 return A[np.argmin(np.abs(np.array(A)-val))] 

11 

12 

13class HourglassMetric(BaseMetric): 

14 """Plot the filters used as a function of time. Must be used with the Hourglass Slicer.""" 

15 

16 def __init__(self, telescope='LSST', mjdCol='observationStartMJD', filterCol='filter', 

17 nightCol='night', **kwargs): 

18 self.mjdCol = mjdCol 

19 self.filterCol = filterCol 

20 self.nightCol = nightCol 

21 cols = [self.mjdCol, self.filterCol, self.nightCol] 

22 super(HourglassMetric, self).__init__(col=cols, metricDtype='object', **kwargs) 

23 self.telescope = Site(name=telescope) 

24 

25 def run(self, dataSlice, slicePoint=None): 

26 

27 import ephem 

28 dataSlice.sort(order=self.mjdCol) 

29 unights, uindx = np.unique(dataSlice[self.nightCol], return_index=True) 

30 

31 names = ['mjd', 'midnight', 'moonPer', 'twi6_rise', 'twi6_set', 'twi12_rise', 

32 'twi12_set', 'twi18_rise', 'twi18_set'] 

33 types = ['float']*len(names) 

34 pernight = np.zeros(len(unights), dtype=list(zip(names, types))) 

35 

36 pernight['mjd'] = dataSlice[self.mjdCol][uindx] 

37 

38 left = np.searchsorted(dataSlice[self.nightCol], unights) 

39 

40 lsstObs = ephem.Observer() 

41 lsstObs.lat = self.telescope.latitude_rad 

42 lsstObs.lon = self.telescope.longitude_rad 

43 lsstObs.elevation = self.telescope.height 

44 horizons = ['-6', '-12', '-18'] 

45 key = ['twi6', 'twi12', 'twi18'] 

46 

47 obsList = [] 

48 S = ephem.Sun() 

49 moon = ephem.Moon() 

50 for h in horizons: 

51 obs = ephem.Observer() 

52 obs.lat, obs.lon, obs.elevation = self.telescope.latitude_rad, self.telescope.longitude_rad, \ 

53 self.telescope.height 

54 obs.horizon = h 

55 obsList.append(obs) 

56 

57 # Convert ...pyephem uses 1899 as it's zero-day, and MJD has Nov 17 1858 as zero-day. 

58 doff = ephem.Date(0)-ephem.Date('1858/11/17') 

59 

60 for i, mjd in enumerate(pernight['mjd']): 

61 mjd = mjd-doff 

62 

63 pernight['midnight'][i] = nearestVal([lsstObs.previous_antitransit(S, start=mjd), 

64 lsstObs.next_antitransit(S, start=mjd)], mjd) + doff 

65 moon.compute(mjd) 

66 pernight['moonPer'][i] = moon.phase 

67 for j, obs in enumerate(obsList): 

68 pernight[key[j]+'_rise'][i] = obs.next_rising(S, start=pernight['midnight'][i]-doff, 

69 use_center=True) + doff 

70 

71 pernight[key[j]+'_set'][i] = obs.previous_setting(S, start=pernight['midnight'][i]-doff, 

72 use_center=True) + doff 

73 

74 # Define the breakpoints as where either the filter changes OR 

75 # there's more than a 2 minute gap in observing 

76 good = np.where((dataSlice[self.filterCol] != np.roll(dataSlice[self.filterCol], 1)) | 

77 (np.abs(np.roll(dataSlice[self.mjdCol], 1) - 

78 dataSlice[self.mjdCol]) > 120./3600./24.))[0] 

79 good = np.concatenate((good, [0], [len(dataSlice[self.filterCol])])) 

80 good = np.unique(good) 

81 left = good[:-1] 

82 right = good[1:]-1 

83 good = np.ravel(list(zip(left, right))) 

84 

85 names = ['mjd', 'midnight', 'filter'] 

86 types = ['float', 'float', (np.str_ ,1)] 

87 perfilter = np.zeros((good.size), dtype=list(zip(names, types))) 

88 perfilter['mjd'] = dataSlice[self.mjdCol][good] 

89 perfilter['filter'] = dataSlice[self.filterCol][good] 

90 for i, mjd in enumerate(perfilter['mjd']): 

91 mjd = mjd - doff 

92 perfilter['midnight'][i] = nearestVal([lsstObs.previous_antitransit(S, start=mjd), 

93 lsstObs.next_antitransit(S, start=mjd)], mjd)+doff 

94 

95 return {'pernight': pernight, 'perfilter': perfilter}