Coverage for python/lsst/sims/maf/utils/mafUtils.py : 14%

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
2import healpy as hp
3import warnings
4from scipy.stats import binned_statistic
5from lsst.sims.utils import int_binned_stat
8__all__ = ['optimalBins', 'percentileClipping',
9 'gnomonic_project_toxy', 'radec2pix', 'collapse_night']
12def coaddM5(mags):
13 """Coadded depth, assuming Gaussian noise
14 """
15 return 1.25 * np.log10(np.sum(10.**(0.8*np.array(mags))))
18def collapse_night(dataSlice, nightCol='night', filterCol='filter',
19 m5Col='fiveSigmaDepth', mjdCol='observationStartMJD'):
20 """Collapse a dataSlice down by night. Convert the MJD to the median MJD per night and coadd 5-sigma depth (per filter)
21 """
22 # Make an explicit copy so we don't clobber things
23 result = dataSlice.copy()
24 result.sort(order=[nightCol, filterCol])
26 filters = np.unique(result[filterCol])
28 for filtername in filters:
29 infilt = np.where(result[filterCol] == filtername)[0]
30 unight, indices = np.unique(result[nightCol][infilt], return_inverse=True)
31 right = unight+0.5
32 bins = [unight[0]-0.5] + right.tolist()
33 coadds, be, bn = binned_statistic(result[nightCol][infilt],
34 result[m5Col][infilt], bins=bins,
35 statistic=coaddM5)
36 # now we just clobber the m5Col with the coadd for the night
37 result[m5Col][infilt] = coadds[indices]
39 unights, median_mjd_per_night = int_binned_stat(dataSlice[nightCol][infilt],
40 dataSlice[mjdCol][infilt],
41 statistic=np.median)
42 dataSlice[mjdCol][infilt] = median_mjd_per_night[indices]
44 # Note, we could also clobber exposure MJD, exposure time, etc. But I don't think they
45 # get used later, so maybe OK.
47 # Make a string that is the combination of night and filter
48 night_filt = np.char.add(dataSlice[nightCol].astype(str), dataSlice[filterCol].astype(str))
49 u_nf, indx = np.unique(night_filt, return_index=True)
50 dataSlice = dataSlice[indx]
51 dataSlice.sort(order=[mjdCol])
53 return dataSlice
57def optimalBins(datain, binmin=None, binmax=None, nbinMax=200, nbinMin=1):
58 """
59 Set an 'optimal' number of bins using the Freedman-Diaconis rule.
61 Parameters
62 ----------
63 datain : numpy.ndarray or numpy.ma.MaskedArray
64 The data for which we want to set the binsize.
65 binmin : float
66 The minimum bin value to consider (if None, uses minimum data value).
67 binmax : float
68 The maximum bin value to consider (if None, uses maximum data value).
69 nbinMax : int
70 The maximum number of bins to create. Sometimes the 'optimal binsize' implies
71 an unreasonably large number of bins, if the data distribution is unusual.
72 nbinMin : int
73 The minimum number of bins to create. Default is 1.
75 Returns
76 -------
77 int
78 The number of bins.
79 """
80 # if it's a masked array, only use unmasked values
81 if hasattr(datain, 'compressed'):
82 data = datain.compressed()
83 else:
84 data = datain
85 # Check that any good data values remain.
86 if data.size == 0:
87 nbins = nbinMax
88 warnings.warn('No unmasked data available for calculating optimal bin size: returning %i bins' %(nbins))
89 # Else proceed.
90 else:
91 if binmin is None:
92 binmin = np.nanmin(data)
93 if binmax is None:
94 binmax = np.nanmax(data)
95 cond = np.where((data >= binmin) & (data <= binmax))[0]
96 # Check if any data points remain within binmin/binmax.
97 if np.size(data[cond]) == 0:
98 nbins = nbinMax
99 warnings.warn('No data available for calculating optimal bin size within range of %f, %f'
100 %(binmin, binmax) + ': returning %i bins' %(nbins))
101 else:
102 iqr = np.percentile(data[cond], 75) - np.percentile(data[cond], 25)
103 binwidth = 2 * iqr * (np.size(data[cond])**(-1./3.))
104 nbins = (binmax - binmin) / binwidth
105 if nbins > nbinMax:
106 warnings.warn('Optimal bin calculation tried to make %.0f bins, returning %i'%(nbins, nbinMax))
107 nbins = nbinMax
108 if nbins < nbinMin:
109 warnings.warn('Optimal bin calculation tried to make %.0f bins, returning %i'%(nbins, nbinMin))
110 nbins = nbinMin
111 if np.isnan(nbins):
112 warnings.warn('Optimal bin calculation calculated NaN: returning %i' %(nbinMax))
113 nbins = nbinMax
114 return int(nbins)
117def percentileClipping(data, percentile=95.):
118 """
119 Calculate the minimum and maximum values of a distribution of points, after
120 discarding data more than 'percentile' from the median.
121 This is useful for determining useful data ranges for plots.
122 Note that 'percentile' percent of the data is retained.
124 Parameters
125 ----------
126 data : numpy.ndarray
127 The data to clip.
128 percentile : float
129 Retain values within percentile of the median.
131 Returns
132 -------
133 float, float
134 The minimum and maximum values of the clipped data.
135 """
136 lower_percentile = (100 - percentile) / 2.0
137 upper_percentile = 100 - lower_percentile
138 min_value = np.percentile(data, lower_percentile)
139 max_value = np.percentile(data, upper_percentile)
140 return min_value, max_value
142def gnomonic_project_toxy(RA1, Dec1, RAcen, Deccen):
143 """
144 Calculate the x/y values of RA1/Dec1 in a gnomonic projection with center at RAcen/Deccen.
146 Parameters
147 ----------
148 RA1 : numpy.ndarray
149 RA values of the data to be projected, in radians.
150 Dec1 : numpy.ndarray
151 Dec values of the data to be projected, in radians.
152 RAcen: float
153 RA value of the center of the projection, in radians.
154 Deccen : float
155 Dec value of the center of the projection, in radians.
157 Returns
158 -------
159 numpy.ndarray, numpy.ndarray
160 The x/y values of the projected RA1/Dec1 positions.
161 """
162 cosc = np.sin(Deccen) * np.sin(Dec1) + np.cos(Deccen) * np.cos(Dec1) * np.cos(RA1-RAcen)
163 x = np.cos(Dec1) * np.sin(RA1-RAcen) / cosc
164 y = (np.cos(Deccen)*np.sin(Dec1) - np.sin(Deccen)*np.cos(Dec1)*np.cos(RA1-RAcen)) / cosc
165 return x, y
168def radec2pix(nside, ra, dec):
169 """
170 Calculate the nearest healpixel ID of an RA/Dec array, assuming nside.
172 Parameters
173 ----------
174 nside : int
175 The nside value of the healpix grid.
176 ra : numpy.ndarray
177 The RA values to be converted to healpix ids, in radians.
178 dec : numpy.ndarray
179 The Dec values to be converted to healpix ids, in radians.
181 Returns
182 -------
183 numpy.ndarray
184 The healpix ids.
185 """
186 lat = np.pi/2. - dec
187 hpid = hp.ang2pix(nside, lat, ra )
188 return hpid