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

1import numpy as np 

2from .baseMetric import BaseMetric 

3from scipy import stats 

4 

5__all__ = ['HistogramMetric','AccumulateMetric', 'AccumulateCountMetric', 

6 'HistogramM5Metric', 'AccumulateM5Metric', 'AccumulateUniformityMetric'] 

7 

8 

9class VectorMetric(BaseMetric): 

10 """ 

11 Base for metrics that return a vector 

12 """ 

13 def __init__(self, bins=None, binCol='night', col='night', units=None, metricDtype=float, **kwargs): 

14 super(VectorMetric,self).__init__(col=[col,binCol],units=units,metricDtype=metricDtype,**kwargs) 

15 self.bins = bins 

16 self.binCol = binCol 

17 self.shape = np.size(bins)-1 

18 

19class HistogramMetric(VectorMetric): 

20 """ 

21 A wrapper to stats.binned_statistic 

22 """ 

23 def __init__(self, bins=None, binCol='night', col='night', units='Count', statistic='count', 

24 metricDtype=float, **kwargs): 

25 self.statistic = statistic 

26 self.col=col 

27 super(HistogramMetric,self).__init__(col=col, bins=bins, binCol=binCol, units=units, 

28 metricDtype=metricDtype,**kwargs) 

29 

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

31 dataSlice.sort(order=self.binCol) 

32 result, binEdges,binNumber = stats.binned_statistic(dataSlice[self.binCol], 

33 dataSlice[self.col], 

34 bins=self.bins, 

35 statistic=self.statistic) 

36 return result 

37 

38class AccumulateMetric(VectorMetric): 

39 """ 

40 Calculate the accumulated stat 

41 """ 

42 def __init__(self, col='night', bins=None, binCol='night', function=np.add, 

43 metricDtype=float, **kwargs): 

44 self.function = function 

45 super(AccumulateMetric,self).__init__(col=col,binCol=binCol, bins=bins, 

46 metricDtype=metricDtype,**kwargs) 

47 self.col=col 

48 

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

50 dataSlice.sort(order=self.binCol) 

51 

52 result = self.function.accumulate(dataSlice[self.col]) 

53 indices = np.searchsorted(dataSlice[self.binCol], self.bins[1:], side='right') 

54 indices[np.where(indices >= np.size(result))] = np.size(result)-1 

55 result = result[indices] 

56 result[np.where(indices == 0)] = self.badval 

57 return result 

58 

59class AccumulateCountMetric(AccumulateMetric): 

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

61 dataSlice.sort(order=self.binCol) 

62 toCount = np.ones(dataSlice.size, dtype=int) 

63 result = self.function.accumulate(toCount) 

64 indices = np.searchsorted(dataSlice[self.binCol], self.bins[1:], side='right') 

65 indices[np.where(indices >= np.size(result))] = np.size(result)-1 

66 result = result[indices] 

67 result[np.where(indices == 0)] = self.badval 

68 return result 

69 

70class HistogramM5Metric(HistogramMetric): 

71 """ 

72 Calculate the coadded depth for each bin (e.g., per night). 

73 """ 

74 def __init__(self, bins=None, binCol='night', m5Col='fiveSigmaDepth', units='mag', 

75 metricName='HistogramM5Metric',**kwargs): 

76 

77 super(HistogramM5Metric,self).__init__(col=m5Col,binCol=binCol, bins=bins, 

78 metricName=metricName, 

79 units=units,**kwargs) 

80 self.m5Col=m5Col 

81 

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

83 dataSlice.sort(order=self.binCol) 

84 flux = 10.**(.8*dataSlice[self.m5Col]) 

85 result, binEdges,binNumber = stats.binned_statistic(dataSlice[self.binCol], 

86 flux, 

87 bins=self.bins, 

88 statistic='sum') 

89 noFlux = np.where(result == 0.) 

90 result = 1.25*np.log10(result) 

91 result[noFlux] = self.badval 

92 return result 

93 

94class AccumulateM5Metric(AccumulateMetric): 

95 def __init__(self, bins=None, binCol='night', m5Col='fiveSigmaDepth', 

96 metricName='AccumulateM5Metric',**kwargs): 

97 self.m5Col = m5Col 

98 super(AccumulateM5Metric,self).__init__(bins=bins, binCol=binCol,col=m5Col, 

99 metricName=metricName,**kwargs) 

100 

101 

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

103 dataSlice.sort(order=self.binCol) 

104 flux = 10.**(.8*dataSlice[self.m5Col]) 

105 

106 result = np.add.accumulate(flux) 

107 indices = np.searchsorted(dataSlice[self.binCol], self.bins[1:], side='right') 

108 indices[np.where(indices >= np.size(result))] = np.size(result)-1 

109 result = result[indices] 

110 result = 1.25*np.log10(result) 

111 result[np.where(indices == 0)] = self.badval 

112 return result 

113 

114 

115class AccumulateUniformityMetric(AccumulateMetric): 

116 """ 

117 Make a 2D version of UniformityMetric 

118 """ 

119 def __init__(self, bins=None, binCol='night', expMJDCol='observationStartMJD', 

120 metricName='AccumulateUniformityMetric',surveyLength=10., 

121 units='Fraction', **kwargs): 

122 self.expMJDCol = expMJDCol 

123 if bins is None: 

124 bins = np.arange(0,np.ceil(surveyLength*365.25))-.5 

125 super(AccumulateUniformityMetric,self).__init__(bins=bins, binCol=binCol,col=expMJDCol, 

126 metricName=metricName,units=units,**kwargs) 

127 self.surveyLength = surveyLength 

128 

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

130 dataSlice.sort(order=self.binCol) 

131 if dataSlice.size == 1: 

132 return np.ones(self.bins.size-1, dtype=float) 

133 

134 visitsPerNight, blah = np.histogram(dataSlice[self.binCol], bins=self.bins) 

135 visitsPerNight = np.add.accumulate(visitsPerNight) 

136 expectedPerNight = np.arange(0.,self.bins.size-1)/(self.bins.size-2) * dataSlice.size 

137 

138 D_max = np.abs(visitsPerNight-expectedPerNight) 

139 D_max = np.maximum.accumulate(D_max) 

140 result = D_max/expectedPerNight.max() 

141 return result