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 

3import copy 

4import matplotlib.pyplot as plt 

5from .plotHandler import BasePlotter 

6from matplotlib.patches import Ellipse 

7 

8__all__ = ['NeoDistancePlotter'] 

9 

10 

11class NeoDistancePlotter(BasePlotter): 

12 """ 

13 Special plotter to calculate and plot the maximum distance an H=22 NEO could be observable to, 

14 in any particular particular opsim observation. 

15 """ 

16 def __init__(self, step=.01, eclipMax=10., eclipMin=-10.): 

17 """ 

18 eclipMin/Max: only plot observations within X degrees of the ecliptic plane 

19 step: Step size to use for radial bins. Default is 0.01 AU. 

20 """ 

21 self.plotType = 'neoxyPlotter' 

22 self.objectPlotter = True 

23 self.defaultPlotDict = {'title': None, 'xlabel': 'X (AU)', 

24 'ylabel': 'Y (AU)', 'xMin': -1.5, 'xMax': 1.5, 

25 'yMin': -.25, 'yMax': 2.5, 'units': 'Count'} 

26 self.filter2color = {'u': 'purple', 'g': 'blue', 'r': 'green', 

27 'i': 'cyan', 'z': 'orange', 'y': 'red'} 

28 self.filterColName = 'filter' 

29 self.step = step 

30 self.eclipMax = np.radians(eclipMax) 

31 self.eclipMin = np.radians(eclipMin) 

32 

33 def __call__(self, metricValue, slicer, userPlotDict, fignum=None): 

34 """ 

35 Parameters 

36 ---------- 

37 metricValue : numpy.ma.MaskedArray 

38 Metric values calculated by lsst.sims.maf.metrics.PassMetric 

39 slicer : lsst.sims.maf.slicers.UniSlicer 

40 userPlotDict: dict 

41 Dictionary of plot parameters set by user (overrides default values). 

42 fignum : int 

43 Matplotlib figure number to use (default = None, starts new figure). 

44 

45 Returns 

46 ------- 

47 int 

48 Matplotlib figure number used to create the plot. 

49 """ 

50 fig = plt.figure(fignum) 

51 ax = fig.add_subplot(111) 

52 

53 inPlane = np.where((metricValue[0]['eclipLat'] >= self.eclipMin) & 

54 (metricValue[0]['eclipLat'] <= self.eclipMax)) 

55 

56 plotDict = {} 

57 plotDict.update(self.defaultPlotDict) 

58 plotDict.update(userPlotDict) 

59 

60 planetProps = {'Earth': 1., 'Venus': 0.72, 'Mars': 1.52, 'Mercury': 0.39} 

61 

62 planets = [] 

63 for prop in planetProps: 

64 planets.append(Ellipse((0, 0), planetProps[prop] * 2, planetProps[prop] * 2, fill=False)) 

65 

66 for planet in planets: 

67 ax.add_artist(planet) 

68 

69 # Let's make a 2-d histogram in polar coords, then convert and display in cartisian 

70 

71 rStep = self.step 

72 Rvec = np.arange(0, plotDict['xMax'] + rStep, rStep) 

73 thetaStep = np.radians(3.5) 

74 thetavec = np.arange(0, 2 * np.pi + thetaStep, thetaStep) - np.pi 

75 

76 # array to hold histogram values 

77 H = np.zeros((thetavec.size, Rvec.size), dtype=float) 

78 

79 Rgrid, thetagrid = np.meshgrid(Rvec, thetavec) 

80 

81 xgrid = Rgrid * np.cos(thetagrid) 

82 ygrid = Rgrid * np.sin(thetagrid) 

83 

84 for dist, x, y in zip(metricValue[0]['MaxGeoDist'][inPlane], metricValue[0]['NEOHelioX'][inPlane], 

85 metricValue[0]['NEOHelioY'][inPlane]): 

86 

87 theta = np.arctan2(y - 1., x) 

88 diff = np.abs(thetavec - theta) 

89 thetaToUse = thetavec[np.where(diff == diff.min())] 

90 # This is a slow where-clause, should be possible to speed it up using 

91 # np.searchsorted+clever slicing or hist2d to build up the map. 

92 good = np.where((thetagrid == thetaToUse) & (Rgrid <= dist)) 

93 H[good] += 1 

94 

95 # Set the under value to white 

96 myCmap = copy.copy(plt.cm.get_cmap('jet')) 

97 myCmap.set_under('w') 

98 blah = ax.pcolormesh(xgrid, ygrid + 1, H, cmap=myCmap, vmin=.001, shading='auto') 

99 cb = plt.colorbar(blah, ax=ax) 

100 cb.set_label(plotDict['units']) 

101 

102 ax.set_xlabel(plotDict['xlabel']) 

103 ax.set_ylabel(plotDict['ylabel']) 

104 ax.set_title(plotDict['title']) 

105 ax.set_ylim([plotDict['yMin'], plotDict['yMax']]) 

106 ax.set_xlim([plotDict['xMin'], plotDict['xMax']]) 

107 

108 ax.plot([0], [1], marker='o', color='b') 

109 ax.plot([0], [0], marker='o', color='y') 

110 

111 return fig.number