Coverage for python/lsst/sims/maf/metrics/hourglassMetric.py : 13%

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
6__all__ = ['HourglassMetric']
9def nearestVal(A, val):
10 return A[np.argmin(np.abs(np.array(A)-val))]
13class HourglassMetric(BaseMetric):
14 """Plot the filters used as a function of time. Must be used with the Hourglass Slicer."""
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)
25 def run(self, dataSlice, slicePoint=None):
27 import ephem
28 dataSlice.sort(order=self.mjdCol)
29 unights, uindx = np.unique(dataSlice[self.nightCol], return_index=True)
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)))
36 pernight['mjd'] = dataSlice[self.mjdCol][uindx]
38 left = np.searchsorted(dataSlice[self.nightCol], unights)
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']
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)
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')
60 for i, mjd in enumerate(pernight['mjd']):
61 mjd = mjd-doff
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
71 pernight[key[j]+'_set'][i] = obs.previous_setting(S, start=pernight['midnight'][i]-doff,
72 use_center=True) + doff
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)))
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
95 return {'pernight': pernight, 'perfilter': perfilter}