def fOBatch(colmap=None, runName='opsim', extraSql=None, extraMetadata=None, nside=64, benchmarkArea=18000, benchmarkNvisits=825): # Allow user to add dithering. if colmap is None: colmap = ColMapDict('opsimV4') bundleList = [] sql = '' metadata = 'All visits' # Add additional sql constraint (such as wfdWhere) and metadata, if provided. if (extraSql is not None) and (len(extraSql) > 0): sql = extraSql if extraMetadata is None: metadata = extraSql.replace('filter =', '').replace('filter=', '') metadata = metadata.replace('"', '').replace("'", '') if extraMetadata is not None: metadata = extraMetadata subgroup = metadata raCol = colmap['ra'] decCol = colmap['dec'] degrees = colmap['raDecDeg'] # Set up fO metric. slicer = slicers.HealpixSlicer(nside=nside, lonCol=raCol, latCol=decCol, latLonDeg=degrees) displayDict = {'group': 'FO metrics', 'subgroup': subgroup, 'order': 0} # Configure the count metric which is what is used for f0 slicer. metric = metrics.CountMetric(col=colmap['mjd'], metricName='fO') plotDict = {'xlabel': 'Number of Visits', 'Asky': benchmarkArea, 'Nvisit': benchmarkNvisits, 'xMin': 0, 'xMax': 1500} summaryMetrics = [metrics.fOArea(nside=nside, norm=False, metricName='fOArea: Nvisits (#)', Asky=benchmarkArea, Nvisit=benchmarkNvisits), metrics.fOArea(nside=nside, norm=True, metricName='fOArea: Nvisits/benchmark', Asky=benchmarkArea, Nvisit=benchmarkNvisits), metrics.fONv(nside=nside, norm=False, metricName='fONv: Area (sqdeg)', Asky=benchmarkArea, Nvisit=benchmarkNvisits), metrics.fONv(nside=nside, norm=True, metricName='fONv: Area/benchmark', Asky=benchmarkArea, Nvisit=benchmarkNvisits)] caption = 'The FO metric evaluates the overall efficiency of observing. ' caption += ('fOArea: Nvisits = %.1f sq degrees receive at least this many visits out of %d. ' % (benchmarkArea, benchmarkNvisits)) caption += ('fONv: Area = this many square degrees out of %.1f receive at least %d visits.' % (benchmarkArea, benchmarkNvisits)) displayDict['caption'] = caption bundle = mb.MetricBundle(metric, slicer, sql, plotDict=plotDict, displayDict=displayDict, summaryMetrics=summaryMetrics, plotFuncs=[plots.FOPlot()], metadata=metadata) bundleList.append(bundle) # Set the runName for all bundles and return the bundleDict. for b in bundleList: b.setRunName(runName) return mb.makeBundlesDictFromList(bundleList)
def testfOArea(self): """Test fOArea metric.""" nside=128 metric = metrics.fOArea(col='ack',nside=nside, Nvisit=825, Asky=18000.) npix = hp.nside2npix(nside) names=['blah'] types = [float] data = np.zeros(npix, dtype=zip(names,types)) # Set all the pixels to have 826 counts data['blah'] = data['blah']+826 slicePoint = {'sid':0} result1 = metric.run(data, slicePoint) np.testing.assert_almost_equal(result1*825, 826) data['blah'][:data.size/2]=0 result2 = metric.run(data, slicePoint)
def testfOArea(self): """Test fOArea metric.""" nside = 128 npix = hp.nside2npix(nside) names = ['metricdata'] types = [int] data = np.zeros(npix, dtype=list(zip(names, types))) data['metricdata'] += 826 metric = metrics.fOArea(col='ack', nside=nside, Nvisit=825, Asky=18000.) slicePoint = {'sid': 0} result = metric.run(data, slicePoint) # fOArea returns the area with at least Nvisits. deginsph = 129600. / np.pi np.testing.assert_almost_equal(result, deginsph) data['metricdata'][:data.size // 2] = 0 result = metric.run(data, slicePoint) np.testing.assert_almost_equal(result, deginsph / 2.)
def testfOArea(self): """Test fOArea metric.""" nside = 128 metric = metrics.fOArea(col='ack', nside=nside, Nvisit=825, Asky=18000.) npix = hp.nside2npix(nside) names = ['blah'] types = [float] data = np.zeros(npix, dtype=zip(names, types)) # Set all the pixels to have 826 counts data['blah'] = data['blah'] + 826 slicePoint = {'sid': 0} result1 = metric.run(data, slicePoint) np.testing.assert_almost_equal(result1 * 825, 826) data['blah'][:data.size / 2] = 0 result2 = metric.run(data, slicePoint)
def makeBundleList(dbFile, runName=None, nside=64, benchmark='design', lonCol='fieldRA', latCol='fieldDec', seeingCol='FWHMgeom'): """ make a list of metricBundle objects to look at the scientific performance of an opsim run. """ # List to hold everything we're going to make bundleList = [] # List to hold metrics that shouldn't be saved noSaveBundleList = [] # Connect to the databse opsimdb = utils.connectOpsimDb(dbFile) if runName is None: runName = os.path.basename(dbFile).replace('_sqlite.db', '') # Fetch the proposal ID values from the database propids, propTags = opsimdb.fetchPropInfo() # Fetch the telescope location from config lat, lon, height = opsimdb.fetchLatLonHeight() # Add metadata regarding dithering/non-dithered. commonname = ''.join([a for a in lonCol if a in latCol]) if commonname == 'field': slicermetadata = ' (non-dithered)' else: slicermetadata = ' (%s)' % (commonname) # Construct a WFD SQL where clause so multiple propIDs can query by WFD: wfdWhere = utils.createSQLWhere('WFD', propTags) print '#FYI: WFD "where" clause: %s' % (wfdWhere) ddWhere = utils.createSQLWhere('DD', propTags) print '#FYI: DD "where" clause: %s' % (ddWhere) # Set up benchmark values, scaled to length of opsim run. runLength = opsimdb.fetchRunLength() if benchmark == 'requested': # Fetch design values for seeing/skybrightness/single visit depth. benchmarkVals = utils.scaleBenchmarks(runLength, benchmark='design') # Update nvisits with requested visits from config files. benchmarkVals['nvisits'] = opsimdb.fetchRequestedNvisits(propId=propTags['WFD']) # Calculate expected coadded depth. benchmarkVals['coaddedDepth'] = utils.calcCoaddedDepth(benchmarkVals['nvisits'], benchmarkVals['singleVisitDepth']) elif (benchmark == 'stretch') or (benchmark == 'design'): # Calculate benchmarks for stretch or design. benchmarkVals = utils.scaleBenchmarks(runLength, benchmark=benchmark) benchmarkVals['coaddedDepth'] = utils.calcCoaddedDepth(benchmarkVals['nvisits'], benchmarkVals['singleVisitDepth']) else: raise ValueError('Could not recognize benchmark value %s, use design, stretch or requested.' % (benchmark)) # Check that nvisits is not set to zero (for very short run length). for f in benchmarkVals['nvisits']: if benchmarkVals['nvisits'][f] == 0: print 'Updating benchmark nvisits value in %s to be nonzero' % (f) benchmarkVals['nvisits'][f] = 1 # Set values for min/max range of nvisits for All/WFD and DD plots. These are somewhat arbitrary. nvisitsRange = {} nvisitsRange['all'] = {'u': [20, 80], 'g': [50, 150], 'r': [100, 250], 'i': [100, 250], 'z': [100, 300], 'y': [100, 300]} nvisitsRange['DD'] = {'u': [6000, 10000], 'g': [2500, 5000], 'r': [5000, 8000], 'i': [5000, 8000], 'z': [7000, 10000], 'y': [5000, 8000]} # Scale these ranges for the runLength. scale = runLength / 10.0 for prop in nvisitsRange: for f in nvisitsRange[prop]: for i in [0, 1]: nvisitsRange[prop][f][i] = int(np.floor(nvisitsRange[prop][f][i] * scale)) # Filter list, and map of colors (for plots) to filters. filters = ['u', 'g', 'r', 'i', 'z', 'y'] colors = {'u': 'cyan', 'g': 'g', 'r': 'y', 'i': 'r', 'z': 'm', 'y': 'k'} filtorder = {'u': 1, 'g': 2, 'r': 3, 'i': 4, 'z': 5, 'y': 6} # Easy way to run through all fi # Set up a list of common summary stats commonSummary = [metrics.MeanMetric(), metrics.RobustRmsMetric(), metrics.MedianMetric(), metrics.PercentileMetric(metricName='25th%ile', percentile=25), metrics.PercentileMetric(metricName='75th%ile', percentile=75), metrics.MinMetric(), metrics.MaxMetric()] allStats = commonSummary # Set up some 'group' labels reqgroup = 'A: Required SRD metrics' depthgroup = 'B: Depth per filter' uniformitygroup = 'C: Uniformity' airmassgroup = 'D: Airmass distribution' seeinggroup = 'E: Seeing distribution' transgroup = 'F: Transients' sngroup = 'G: SN Ia' altAzGroup = 'H: Alt Az' rangeGroup = 'I: Range of Dates' intergroup = 'J: Inter-Night' phaseGroup = 'K: Max Phase Gap' NEOGroup = 'L: NEO Detection' # Set up an object to track the metricBundles that we want to combine into merged plots. mergedHistDict = {} # Set the histogram merge function. mergeFunc = plots.HealpixHistogram() keys = ['NVisits', 'coaddm5', 'NormEffTime', 'Minseeing', 'seeingAboveLimit', 'minAirmass', 'fracAboveAirmass'] for key in keys: mergedHistDict[key] = plots.PlotBundle(plotFunc=mergeFunc) ## # Calculate the fO metrics for all proposals and WFD only. order = 0 for prop in ('All prop', 'WFD only'): if prop == 'All prop': metadata = 'All Visits' + slicermetadata sqlconstraint = '' if prop == 'WFD only': metadata = 'WFD only' + slicermetadata sqlconstraint = '%s' % (wfdWhere) # Configure the count metric which is what is used for f0 slicer. m1 = metrics.CountMetric(col='expMJD', metricName='fO') plotDict = {'xlabel': 'Number of Visits', 'Asky': benchmarkVals['Area'], 'Nvisit': benchmarkVals['nvisitsTotal'], 'xMin': 0, 'xMax': 1500} summaryMetrics = [metrics.fOArea(nside=nside, norm=False, metricName='fOArea: Nvisits (#)', Asky=benchmarkVals['Area'], Nvisit=benchmarkVals['nvisitsTotal']), metrics.fOArea(nside=nside, norm=True, metricName='fOArea: Nvisits/benchmark', Asky=benchmarkVals['Area'], Nvisit=benchmarkVals['nvisitsTotal']), metrics.fONv(nside=nside, norm=False, metricName='fONv: Area (sqdeg)', Asky=benchmarkVals['Area'], Nvisit=benchmarkVals['nvisitsTotal']), metrics.fONv(nside=nside, norm=True, metricName='fONv: Area/benchmark', Asky=benchmarkVals['Area'], Nvisit=benchmarkVals['nvisitsTotal'])] caption = 'The FO metric evaluates the overall efficiency of observing. ' caption += ('fOArea: Nvisits = %.1f sq degrees receive at least this many visits out of %d. ' % (benchmarkVals['Area'], benchmarkVals['nvisitsTotal'])) caption += ('fONv: Area = this many square degrees out of %.1f receive at least %d visits.' % (benchmarkVals['Area'], benchmarkVals['nvisitsTotal'])) displayDict = {'group': reqgroup, 'subgroup': 'F0', 'displayOrder': order, 'caption': caption} order += 1 slicer = slicers.HealpixSlicer(nside=nside, lonCol=lonCol, latCol=latCol) bundle = metricBundles.MetricBundle(m1, slicer, sqlconstraint, plotDict=plotDict, displayDict=displayDict, summaryMetrics=summaryMetrics, plotFuncs=[plots.FOPlot()], runName=runName, metadata=metadata) bundleList.append(bundle) ### # Calculate the Rapid Revisit Metrics. order = 0 metadata = 'All Visits' + slicermetadata sqlconstraint = '' dTmin = 40.0 # seconds dTmax = 30.0 # minutes minNvisit = 100 pixArea = float(hp.nside2pixarea(nside, degrees=True)) scale = pixArea * hp.nside2npix(nside) cutoff1 = 0.15 extraStats1 = [metrics.FracBelowMetric(cutoff=cutoff1, scale=scale, metricName='Area (sq deg)')] extraStats1.extend(commonSummary) slicer = slicers.HealpixSlicer(nside=nside, lonCol=lonCol, latCol=latCol) m1 = metrics.RapidRevisitMetric(metricName='RapidRevisitUniformity', dTmin=dTmin / 60.0 / 60.0 / 24.0, dTmax=dTmax / 60.0 / 24.0, minNvisits=minNvisit) plotDict = {'xMin': 0, 'xMax': 1} summaryStats = extraStats1 caption = 'Deviation from uniformity for short revisit timescales, between %s and %s seconds, ' % ( dTmin, dTmax) caption += 'for pointings with at least %d visits in this time range. ' % (minNvisit) caption += 'Summary statistic "Area" below indicates the area on the sky which has a ' caption += 'deviation from uniformity of < %.2f.' % (cutoff1) displayDict = {'group': reqgroup, 'subgroup': 'Rapid Revisit', 'displayOrder': order, 'caption': caption} bundle = metricBundles.MetricBundle(m1, slicer, sqlconstraint, plotDict=plotDict, displayDict=displayDict, summaryMetrics=summaryStats, runName=runName, metadata=metadata) bundleList.append(bundle) order += 1 m2 = metrics.NRevisitsMetric(dT=dTmax) plotDict = {'xMin': 0, 'xMax': 1000, 'logScale': True} cutoff2 = 800 extraStats2 = [metrics.FracAboveMetric(cutoff=cutoff2, scale=scale, metricName='Area (sq deg)')] extraStats2.extend(commonSummary) caption = 'Number of consecutive visits with return times faster than %.1f minutes, ' % dTmax caption += 'in any filter, all proposals. ' caption += 'Summary statistic "Area" below indicates the area on the sky which has more than ' caption += '%d revisits within this time window.' % (cutoff2) summaryStats = extraStats2 displayDict = {'group': reqgroup, 'subgroup': 'Rapid Revisit', 'displayOrder': order, 'caption': caption} bundle = metricBundles.MetricBundle(m2, slicer, sqlconstraint, plotDict=plotDict, displayDict=displayDict, summaryMetrics=summaryStats, runName=runName, metadata=metadata) bundleList.append(bundle) order += 1 m3 = metrics.NRevisitsMetric(dT=dTmax, normed=True) plotDict = {'xMin': 0, 'xMax': 1, 'cbarFormat': '%.1f'} cutoff3 = 0.6 extraStats3 = [metrics.FracAboveMetric(cutoff=cutoff3, scale=scale, metricName='Area (sq deg)')] extraStats3.extend(commonSummary) summaryStats = extraStats3 caption = 'Fraction of total visits where consecutive visits have return times faster ' caption += 'than %.1f minutes, in any filter, all proposals. ' % (dTmax) caption += 'Summary statistic "Area" below indicates the area on the sky which has more ' caption += 'than %d revisits within this time window.' % (cutoff3) displayDict = {'group': reqgroup, 'subgroup': 'Rapid Revisit', 'displayOrder': order, 'caption': caption} bundle = metricBundles.MetricBundle(m3, slicer, sqlconstraint, plotDict=plotDict, displayDict=displayDict, summaryMetrics=summaryStats, runName=runName, metadata=metadata) bundleList.append(bundle) order += 1 # And add a histogram of the time between quick revisits. binMin = 0 binMax = 120. binsize = 3. bins_metric = np.arange(binMin / 60.0 / 24.0, (binMax + binsize) / 60. / 24., binsize / 60. / 24.) bins_plot = bins_metric * 24.0 * 60.0 m1 = metrics.TgapsMetric(bins=bins_metric, metricName='dT visits') plotDict = {'bins': bins_plot, 'xlabel': 'dT (minutes)'} caption = ('Histogram of the time between consecutive revisits (<%.1f minutes), over entire sky.' % (binMax)) displayDict = {'group': reqgroup, 'subgroup': 'Rapid Revisit', 'order': order, 'caption': caption} slicer = slicers.HealpixSlicer(nside=nside, lonCol=lonCol, latCol=latCol) plotFunc = plots.SummaryHistogram() bundle = metricBundles.MetricBundle(m1, slicer, sqlconstraint, plotDict=plotDict, displayDict=displayDict, runName=runName, metadata=metadata, plotFuncs=[plotFunc]) bundleList.append(bundle) order += 1 ## # Trigonometric parallax and proper motion @ r=20 and r=24 slicer = slicers.HealpixSlicer(nside=nside, lonCol=lonCol, latCol=latCol) sqlconstraint = '' order = 0 metric = metrics.ParallaxMetric(metricName='Parallax 20', rmag=20, seeingCol=seeingCol) summaryStats = allStats plotDict = {'cbarFormat': '%.1f', 'xMin': 0, 'xMax': 3} displayDict = {'group': reqgroup, 'subgroup': 'Parallax', 'order': order, 'caption': 'Parallax precision at r=20. (without refraction).'} bundle = metricBundles.MetricBundle(metric, slicer, sqlconstraint, plotDict=plotDict, displayDict=displayDict, summaryMetrics=summaryStats, runName=runName, metadata=metadata) bundleList.append(bundle) order += 1 metric = metrics.ParallaxMetric(metricName='Parallax 24', rmag=24, seeingCol=seeingCol) plotDict = {'cbarFormat': '%.1f', 'xMin': 0, 'xMax': 10} displayDict = {'group': reqgroup, 'subgroup': 'Parallax', 'order': order, 'caption': 'Parallax precision at r=24. (without refraction).'} bundle = metricBundles.MetricBundle(metric, slicer, sqlconstraint, plotDict=plotDict, displayDict=displayDict, summaryMetrics=summaryStats, runName=runName, metadata=metadata) bundleList.append(bundle) order += 1 metric = metrics.ParallaxMetric(metricName='Parallax Normed', rmag=24, normalize=True, seeingCol=seeingCol) plotDict = {'xMin': 0.5, 'xMax': 1.0} displayDict = {'group': reqgroup, 'subgroup': 'Parallax', 'order': order, 'caption': 'Normalized parallax (normalized to optimum observation cadence, 1=optimal).'} bundle = metricBundles.MetricBundle(metric, slicer, sqlconstraint, plotDict=plotDict, displayDict=displayDict, summaryMetrics=summaryStats, runName=runName, metadata=metadata) bundleList.append(bundle) order += 1 metric = metrics.ParallaxCoverageMetric(metricName='Parallax Coverage 20', rmag=20, seeingCol=seeingCol) plotDict = {} caption = "Parallax factor coverage for an r=20 star (0 is bad, 0.5-1 is good). " caption += "One expects the parallax factor coverage to vary because stars on the ecliptic " caption += "can be observed when they have no parallax offset while stars at the pole are always " caption += "offset by the full parallax offset.""" displayDict = {'group': reqgroup, 'subgroup': 'Parallax', 'order': order, 'caption': caption} bundle = metricBundles.MetricBundle(metric, slicer, sqlconstraint, plotDict=plotDict, displayDict=displayDict, summaryMetrics=summaryStats, runName=runName, metadata=metadata) bundleList.append(bundle) order += 1 metric = metrics.ParallaxCoverageMetric(metricName='Parallax Coverage 24', rmag=24, seeingCol=seeingCol) plotDict = {} caption = "Parallax factor coverage for an r=24 star (0 is bad, 0.5-1 is good). " caption += "One expects the parallax factor coverage to vary because stars on the ecliptic " caption += "can be observed when they have no parallax offset while stars at the pole are always " caption += "offset by the full parallax offset.""" displayDict = {'group': reqgroup, 'subgroup': 'Parallax', 'order': order, 'caption': caption} bundle = metricBundles.MetricBundle(metric, slicer, sqlconstraint, plotDict=plotDict, displayDict=displayDict, summaryMetrics=summaryStats, runName=runName, metadata=metadata) bundleList.append(bundle) order += 1 metric = metrics.ParallaxHADegenMetric(metricName='Parallax-DCR degeneracy 20', rmag=20, seeingCol=seeingCol) plotDict = {} caption = 'Correlation between parallax offset magnitude and hour angle an r=20 star.' caption += ' (0 is good, near -1 or 1 is bad).' displayDict = {'group': reqgroup, 'subgroup': 'Parallax', 'order': order, 'caption': caption} bundle = metricBundles.MetricBundle(metric, slicer, sqlconstraint, plotDict=plotDict, displayDict=displayDict, summaryMetrics=summaryStats, runName=runName, metadata=metadata) bundleList.append(bundle) order += 1 metric = metrics.ParallaxHADegenMetric(metricName='Parallax-DCR degeneracy 24', rmag=24, seeingCol=seeingCol) plotDict = {} caption = 'Correlation between parallax offset magnitude and hour angle an r=24 star.' caption += ' (0 is good, near -1 or 1 is bad).' displayDict = {'group': reqgroup, 'subgroup': 'Parallax', 'order': order, 'caption': caption} bundle = metricBundles.MetricBundle(metric, slicer, sqlconstraint, plotDict=plotDict, displayDict=displayDict, summaryMetrics=summaryStats, runName=runName, metadata=metadata) bundleList.append(bundle) order += 1 metric = metrics.ProperMotionMetric(metricName='Proper Motion 20', rmag=20, seeingCol=seeingCol) summaryStats = allStats plotDict = {'xMin': 0, 'xMax': 3} displayDict = {'group': reqgroup, 'subgroup': 'Proper Motion', 'order': order, 'caption': 'Proper Motion precision at r=20.'} bundle = metricBundles.MetricBundle(metric, slicer, sqlconstraint, plotDict=plotDict, displayDict=displayDict, summaryMetrics=summaryStats, runName=runName, metadata=metadata) bundleList.append(bundle) order += 1 metric = metrics.ProperMotionMetric(rmag=24, metricName='Proper Motion 24', seeingCol=seeingCol) summaryStats = allStats plotDict = {'xMin': 0, 'xMax': 10} displayDict = {'group': reqgroup, 'subgroup': 'Proper Motion', 'order': order, 'caption': 'Proper Motion precision at r=24.'} bundle = metricBundles.MetricBundle(metric, slicer, sqlconstraint, plotDict=plotDict, displayDict=displayDict, summaryMetrics=summaryStats, runName=runName, metadata=metadata) bundleList.append(bundle) order += 1 metric = metrics.ProperMotionMetric(rmag=24, normalize=True, metricName='Proper Motion Normed', seeingCol=seeingCol) plotDict = {'xMin': 0.2, 'xMax': 0.7} caption = 'Normalized proper motion at r=24. ' caption += '(normalized to optimum observation cadence - start/end. 1=optimal).' displayDict = {'group': reqgroup, 'subgroup': 'Proper Motion', 'order': order, 'caption': caption} bundle = metricBundles.MetricBundle(metric, slicer, sqlconstraint, plotDict=plotDict, displayDict=displayDict, summaryMetrics=summaryStats, runName=runName, metadata=metadata) bundleList.append(bundle) order += 1 ## # Calculate the time uniformity in each filter, for each year. order = 0 slicer = slicers.HealpixSlicer(nside=nside, lonCol=lonCol, latCol=latCol) plotFuncs = [plots.TwoDMap()] step = 0.5 bins = np.arange(0, 365.25 * 10 + 40, 40) - step metric = metrics.AccumulateUniformityMetric(bins=bins) plotDict = {'xlabel': 'Night (days)', 'xextent': [bins.min( ) + step, bins.max() + step], 'cbarTitle': 'Uniformity'} for f in filters: sqlconstraint = 'filter = "%s"' % (f) caption = 'Deviation from uniformity in %s band. ' % f caption += 'Northern Healpixels are at the top of the image.' caption += '(0=perfectly uniform, 1=perfectly nonuniform).' displayDict = {'group': uniformitygroup, 'subgroup': 'per night', 'order': filtorder[f], 'caption': caption} metadata = '%s band' % (f) + slicermetadata bundle = metricBundles.MetricBundle(metric, slicer, sqlconstraint, plotDict=plotDict, displayDict=displayDict, runName=runName, metadata=metadata, plotFuncs=plotFuncs) noSaveBundleList.append(bundle) ## # Depth metrics. slicer = slicers.HealpixSlicer(nside=nside, lonCol=lonCol, latCol=latCol) for f in filters: propCaption = '%s band, all proposals %s' % (f, slicermetadata) sqlconstraint = 'filter = "%s"' % (f) metadata = '%s band' % (f) + slicermetadata # Number of visits. metric = metrics.CountMetric(col='expMJD', metricName='NVisits') plotDict = {'xlabel': 'Number of visits', 'xMin': nvisitsRange['all'][f][0], 'xMax': nvisitsRange['all'][f][1], 'binsize': 5, 'logScale': True, 'nTicks': 4, 'colorMin': 1} summaryStats = allStats displayDict = {'group': depthgroup, 'subgroup': 'Nvisits', 'order': filtorder[f], 'caption': 'Number of visits in filter %s, %s.' % (f, propCaption)} histMerge = {'color': colors[f], 'label': '%s' % (f), 'binsize': 5, 'xMin': nvisitsRange['all'][f][0], 'xMax': nvisitsRange['all'][f][1], 'legendloc': 'upper right'} bundle = metricBundles.MetricBundle(metric, slicer, sqlconstraint, plotDict=plotDict, displayDict=displayDict, runName=runName, metadata=metadata, summaryMetrics=summaryStats) mergedHistDict['NVisits'].addBundle(bundle, plotDict=histMerge) bundleList.append(bundle) # Coadded depth. metric = metrics.Coaddm5Metric() plotDict = {'zp': benchmarkVals['coaddedDepth'][f], 'xMin': -0.8, 'xMax': 0.8, 'xlabel': 'coadded m5 - %.1f' % benchmarkVals['coaddedDepth'][f]} summaryStats = allStats histMerge = {'legendloc': 'upper right', 'color': colors[f], 'label': '%s' % f, 'binsize': .02, 'xlabel': 'coadded m5 - benchmark value'} caption = ('Coadded depth in filter %s, with %s value subtracted (%.1f), %s. ' % (f, benchmark, benchmarkVals['coaddedDepth'][f], propCaption)) caption += 'More positive numbers indicate fainter limiting magnitudes.' displayDict = {'group': depthgroup, 'subgroup': 'Coadded Depth', 'order': filtorder[f], 'caption': caption} bundle = metricBundles.MetricBundle(metric, slicer, sqlconstraint, plotDict=plotDict, displayDict=displayDict, runName=runName, metadata=metadata, summaryMetrics=summaryStats) mergedHistDict['coaddm5'].addBundle(bundle, plotDict=histMerge) bundleList.append(bundle) # Effective time. metric = metrics.TeffMetric(metricName='Normalized Effective Time', normed=True, fiducialDepth=benchmarkVals['singleVisitDepth']) plotDict = {'xMin': 0.1, 'xMax': 1.1} summaryStats = allStats histMerge = {'legendLoc': 'upper right', 'color': colors[f], 'label': '%s' % f, 'binsize': 0.02} caption = ('"Time Effective" in filter %s, calculated with fiducial single-visit depth of %s mag. ' % (f, benchmarkVals['singleVisitDepth'][f])) caption += 'Normalized by the fiducial time effective, if every observation was at ' caption += 'the fiducial depth.' displayDict = {'group': depthgroup, 'subgroup': 'Time Eff.', 'order': filtorder[f], 'caption': caption} bundle = metricBundles.MetricBundle(metric, slicer, sqlconstraint, plotDict=plotDict, displayDict=displayDict, runName=runName, metadata=metadata, summaryMetrics=summaryStats) mergedHistDict['NormEffTime'].addBundle(bundle, plotDict=histMerge) bundleList.append(bundle) # Put in a z=0.5 Type Ia SN, based on Cambridge 2015 workshop notebook. # Check for 1) detection in any band, 2) detection on the rise in any band, # 3) good characterization peaks = {'uPeak': 25.9, 'gPeak': 23.6, 'rPeak': 22.6, 'iPeak': 22.7, 'zPeak': 22.7, 'yPeak': 22.8} peakTime = 15. transDuration = peakTime + 30. # Days metric = metrics.TransientMetric(riseSlope=-2. / peakTime, declineSlope=1.4 / 30.0, transDuration=transDuration, peakTime=peakTime, surveyDuration=runLength, metricName='SNDetection', **peaks) caption = 'Fraction of z=0.5 type Ia SN that are detected in any filter' displayDict = {'group': transgroup, 'subgroup': 'Detected', 'caption': caption} sqlconstraint = '' metadata = '' + slicermetadata plotDict = {} bundle = metricBundles.MetricBundle(metric, slicer, sqlconstraint, plotDict=plotDict, displayDict=displayDict, runName=runName, metadata=metadata) bundleList.append(bundle) metric = metrics.TransientMetric(riseSlope=-2. / peakTime, declineSlope=1.4 / 30.0, transDuration=transDuration, peakTime=peakTime, surveyDuration=runLength, nPrePeak=1, metricName='SNAlert', **peaks) caption = 'Fraction of z=0.5 type Ia SN that are detected pre-peak in any filter' displayDict = {'group': transgroup, 'subgroup': 'Detected on the rise', 'caption': caption} plotDict = {} bundle = metricBundles.MetricBundle(metric, slicer, sqlconstraint, plotDict=plotDict, displayDict=displayDict, runName=runName, metadata=metadata) bundleList.append(bundle) metric = metrics.TransientMetric(riseSlope=-2. / peakTime, declineSlope=1.4 / 30., transDuration=transDuration, peakTime=peakTime, surveyDuration=runLength, metricName='SNLots', nFilters=3, nPrePeak=3, nPerLC=2, **peaks) caption = 'Fraction of z=0.5 type Ia SN that are observed 6 times, 3 pre-peak, ' caption += '3 post-peak, with observations in 3 filters' displayDict = {'group': transgroup, 'subgroup': 'Well observed', 'caption': caption} sqlconstraint = 'filter="r" or filter="g" or filter="i" or filter="z" ' plotDict = {} bundle = metricBundles.MetricBundle(metric, slicer, sqlconstraint, plotDict=plotDict, displayDict=displayDict, runName=runName, metadata=metadata) bundleList.append(bundle) # Good seeing in r/i band metrics, including in first/second years. order = 0 for tcolor, tlabel, timespan in zip(['k', 'g', 'r'], ['10 years', '1 year', '2 years'], ['', ' and night<=365', ' and night<=730']): order += 1 for f in (['r', 'i']): sqlconstraint = 'filter = "%s" %s' % (f, timespan) propCaption = '%s band, all proposals %s, over %s.' % (f, slicermetadata, tlabel) metadata = '%s band, %s' % (f, tlabel) + slicermetadata seeing_limit = 0.7 airmass_limit = 1.2 metric = metrics.MinMetric(col=seeingCol) summaryStats = allStats plotDict = {'xMin': 0.35, 'xMax': 1.5, 'color': tcolor} displayDict = {'group': seeinggroup, 'subgroup': 'Best Seeing', 'order': filtorder[f] * 100 + order, 'caption': 'Minimum FWHMgeom values in %s.' % (propCaption)} histMerge = {'label': '%s %s' % (f, tlabel), 'color': tcolor, 'binsize': 0.03, 'xMin': 0.35, 'xMax': 1.5, 'legendloc': 'upper right'} bundle = metricBundles.MetricBundle(metric, slicer, sqlconstraint, plotDict=plotDict, displayDict=displayDict, runName=runName, metadata=metadata, summaryMetrics=summaryStats) mergedHistDict['Minseeing'].addBundle(bundle, plotDict=histMerge) bundleList.append(bundle) metric = metrics.FracAboveMetric(col=seeingCol, cutoff=seeing_limit) summaryStats = allStats plotDict = {'xMin': 0, 'xMax': 1.1, 'color': tcolor} displayDict = {'group': seeinggroup, 'subgroup': 'Good seeing fraction', 'order': filtorder[f] * 100 + order, 'caption': 'Fraction of total images with FWHMgeom worse than %.1f, in %s' % (seeing_limit, propCaption)} histMerge = {'color': tcolor, 'label': '%s %s' % (f, tlabel), 'binsize': 0.05, 'legendloc': 'upper right'} bundle = metricBundles.MetricBundle(metric, slicer, sqlconstraint, plotDict=plotDict, displayDict=displayDict, runName=runName, metadata=metadata, summaryMetrics=summaryStats) mergedHistDict['seeingAboveLimit'].addBundle(bundle, plotDict=histMerge) bundleList.append(bundle) metric = metrics.MinMetric(col='airmass') plotDict = {'xMin': 1, 'xMax': 1.5, 'color': tcolor} summaryStats = allStats displayDict = {'group': airmassgroup, 'subgroup': 'Best Airmass', 'order': filtorder[f] * 100 + order, 'caption': 'Minimum airmass in %s.' % (propCaption)} histMerge = {'color': tcolor, 'label': '%s %s' % (f, tlabel), 'binsize': 0.03, 'legendloc': 'upper right'} bundle = metricBundles.MetricBundle(metric, slicer, sqlconstraint, plotDict=plotDict, displayDict=displayDict, runName=runName, metadata=metadata, summaryMetrics=summaryStats) mergedHistDict['minAirmass'].addBundle(bundle, plotDict=histMerge) bundleList.append(bundle) metric = metrics.FracAboveMetric(col='airmass', cutoff=airmass_limit) plotDict = {'xMin': 0, 'xMax': 1, 'color': tcolor} summaryStats = allStats displayDict = {'group': airmassgroup, 'subgroup': 'Low airmass fraction', 'order': filtorder[f] * 100 + order, 'caption': 'Fraction of total images with airmass higher than %.2f, in %s' % (airmass_limit, propCaption)} histMerge = {'color': tcolor, 'label': '%s %s' % ( f, tlabel), 'binsize': 0.05, 'legendloc': 'upper right'} bundle = metricBundles.MetricBundle(metric, slicer, sqlconstraint, plotDict=plotDict, displayDict=displayDict, runName=runName, metadata=metadata, summaryMetrics=summaryStats) mergedHistDict['fracAboveAirmass'].addBundle(bundle, plotDict=histMerge) bundleList.append(bundle) # SNe metrics from UK workshop. peaks = {'uPeak': 25.9, 'gPeak': 23.6, 'rPeak': 22.6, 'iPeak': 22.7, 'zPeak': 22.7, 'yPeak': 22.8} peakTime = 15. transDuration = peakTime + 30. # Days metric = metrics.TransientMetric(riseSlope=-2. / peakTime, declineSlope=1.4 / 30.0, transDuration=transDuration, peakTime=peakTime, surveyDuration=runLength, metricName='SNDetection', **peaks) caption = 'Fraction of z=0.5 type Ia SN that are detected at any point in their light curve in any filter' displayDict = {'group': sngroup, 'subgroup': 'Detected', 'caption': caption} sqlconstraint = '' plotDict = {} bundle = metricBundles.MetricBundle(metric, slicer, sqlconstraint, plotDict=plotDict, displayDict=displayDict, runName=runName) bundleList.append(bundle) metric = metrics.TransientMetric(riseSlope=-2. / peakTime, declineSlope=1.4 / 30.0, transDuration=transDuration, peakTime=peakTime, surveyDuration=runLength, nPrePeak=1, metricName='SNAlert', **peaks) caption = 'Fraction of z=0.5 type Ia SN that are detected pre-peak in any filter' displayDict = {'group': sngroup, 'subgroup': 'Detected on the rise', 'caption': caption} plotDict = {} bundle = metricBundles.MetricBundle(metric, slicer, sqlconstraint, plotDict=plotDict, displayDict=displayDict, runName=runName) bundleList.append(bundle) metric = metrics.TransientMetric(riseSlope=-2. / peakTime, declineSlope=1.4 / 30., transDuration=transDuration, peakTime=peakTime, surveyDuration=runLength, metricName='SNLots', nFilters=3, nPrePeak=3, nPerLC=2, **peaks) caption = 'Fraction of z=0.5 type Ia SN that are observed 6 times, 3 pre-peak, ' caption += '3 post-peak, with observations in 3 filters' displayDict = {'group': sngroup, 'subgroup': 'Well observed', 'caption': caption} sqlconstraint = 'filter="r" or filter="g" or filter="i" or filter="z" ' plotDict = {} bundle = metricBundles.MetricBundle(metric, slicer, sqlconstraint, plotDict=plotDict, displayDict=displayDict, runName=runName) bundleList.append(bundle) propIDOrderDict = {} orderVal = 100 for propID in propids: propIDOrderDict[propID] = orderVal orderVal += 100 # Full range of dates: metric = metrics.FullRangeMetric(col='expMJD') plotFuncs = [plots.HealpixSkyMap(), plots.HealpixHistogram()] caption = 'Time span of survey.' sqlconstraint = '' plotDict = {} displayDict = {'group': rangeGroup, 'caption': caption} bundle = metricBundles.MetricBundle(metric, slicer, sqlconstraint, plotDict=plotDict, displayDict=displayDict, runName=runName) bundleList.append(bundle) for f in filters: for propid in propids: displayDict = {'group': rangeGroup, 'subgroup': propids[propid], 'caption': caption, 'order': filtorder[f]} md = '%s, %s' % (f, propids[propid]) sql = 'filter="%s" and propID=%i' % (f, propid) bundle = metricBundles.MetricBundle(metric, slicer, sql, plotDict=plotDict, metadata=md, plotFuncs=plotFuncs, displayDict=displayDict, runName=runName) bundleList.append(bundle) # Alt az plots slicer = slicers.HealpixSlicer(nside=64, latCol='zenithDistance', lonCol='azimuth', useCache=False) metric = metrics.CountMetric('expMJD', metricName='Nvisits as function of Alt/Az') plotDict = {} plotFuncs = [plots.LambertSkyMap()] displayDict = {'group': altAzGroup, 'caption': 'Alt Az pointing distribution'} for f in filters: for propid in propids: displayDict = {'group': altAzGroup, 'subgroup': propids[propid], 'caption': 'Alt Az pointing distribution', 'order': filtorder[f]} md = '%s, %s' % (f, propids[propid]) sql = 'filter="%s" and propID=%i' % (f, propid) bundle = metricBundles.MetricBundle(metric, slicer, sql, plotDict=plotDict, plotFuncs=plotFuncs, metadata=md, displayDict=displayDict, runName=runName) bundleList.append(bundle) sql = '' md = 'all observations' displayDict = {'group': altAzGroup, 'subgroup': 'All Observations', 'caption': 'Alt Az pointing distribution'} bundle = metricBundles.MetricBundle(metric, slicer, sql, plotDict=plotDict, plotFuncs=plotFuncs, metadata=md, displayDict=displayDict, runName=runName) bundleList.append(bundle) # Median inter-night gap (each and all filters) slicer = slicers.HealpixSlicer(nside=nside, lonCol=lonCol, latCol=latCol) metric = metrics.InterNightGapsMetric(metricName='Median Inter-Night Gap') sqls = ['filter = "%s"' % f for f in filters] orders = [filtorder[f] for f in filters] orders.append(0) sqls.append('') for sql, order in zip(sqls, orders): displayDict = {'group': intergroup, 'subgroup': 'Median Gap', 'caption': 'Median gap between days', 'order': order} bundle = metricBundles.MetricBundle(metric, slicer, sql, displayDict=displayDict, runName=runName) bundleList.append(bundle) # Max inter-night gap in r and all bands dslicer = slicers.HealpixSlicer(nside=nside, lonCol='ditheredRA', latCol='ditheredDec') metric = metrics.InterNightGapsMetric(metricName='Max Inter-Night Gap', reduceFunc=np.max) plotDict = {'percentileClip': 95.} for sql, order in zip(sqls, orders): displayDict = {'group': intergroup, 'subgroup': 'Max Gap', 'caption': 'Max gap between nights', 'order': order} bundle = metricBundles.MetricBundle(metric, dslicer, sql, displayDict=displayDict, plotDict=plotDict, runName=runName) bundleList.append(bundle) # largest phase gap for periods periods = [0.1, 1.0, 10., 100.] sqls = {'u': 'filter = "u"', 'r': 'filter="r"', 'g,r,i,z': 'filter="g" or filter="r" or filter="i" or filter="z"', 'all': ''} for sql in sqls.keys(): for period in periods: displayDict = {'group': phaseGroup, 'subgroup': 'period=%.2f days, filter=%s' % (period, sql), 'caption': 'Maximum phase gaps'} metric = metrics.PhaseGapMetric(nPeriods=1, periodMin=period, periodMax=period, metricName='PhaseGap, %.1f' % period) bundle = metricBundles.MetricBundle(metric, slicer, sqls[sql], displayDict=displayDict, runName=runName) bundleList.append(bundle) # NEO XY plots slicer = slicers.UniSlicer() metric = metrics.PassMetric(metricName='NEODistances') stacker = stackers.NEODistStacker() stacker2 = stackers.EclipticStacker() for f in filters: plotFunc = plots.NeoDistancePlotter(eclipMax=10., eclipMin=-10.) caption = 'Observations within 10 degrees of the ecliptic. Distance an H=22 NEO would be detected' displayDict = {'group': NEOGroup, 'subgroup': 'xy', 'order': filtorder[f], 'caption': caption} plotDict = {} sqlconstraint = 'filter = "%s"' % (f) bundle = metricBundles.MetricBundle(metric, slicer, sqlconstraint, displayDict=displayDict, stackerList=[stacker, stacker2], plotDict=plotDict, plotFuncs=[plotFunc]) noSaveBundleList.append(bundle) # Solar elongation sqls = ['filter = "%s"' % f for f in filters] orders = [filtorder[f] for f in filters] sqls.append('') orders.append(0) for sql, order in zip(sqls, orders): plotFuncs = [plots.HealpixSkyMap(), plots.HealpixHistogram()] displayDict = {'group': NEOGroup, 'subgroup': 'Solar Elongation', 'caption': 'Median solar elongation in degrees', 'order': order} metric = metrics.MedianMetric('solarElong') slicer = slicers.HealpixSlicer(nside=nside, lonCol=lonCol, latCol=latCol) bundle = metricBundles.MetricBundle(metric, slicer, sql, displayDict=displayDict, plotFuncs=plotFuncs) bundleList.append(bundle) plotFuncs = [plots.HealpixSkyMap(), plots.HealpixHistogram()] displayDict = {'group': NEOGroup, 'subgroup': 'Solar Elongation', 'caption': 'Minimum solar elongation in degrees', 'order': order} metric = metrics.MinMetric('solarElong') slicer = slicers.HealpixSlicer(nside=nside, lonCol=lonCol, latCol=latCol) bundle = metricBundles.MetricBundle(metric, slicer, sql, displayDict=displayDict, plotFuncs=plotFuncs) bundleList.append(bundle) return (metricBundles.makeBundlesDictFromList(bundleList), mergedHistDict, metricBundles.makeBundlesDictFromList(noSaveBundleList))
def makeBundleList(dbFile, runName=None, nside=64, benchmark='design', lonCol='fieldRA', latCol='fieldDec', seeingCol='seeingFwhmGeom'): """ make a list of metricBundle objects to look at the scientific performance of an opsim run. """ # List to hold everything we're going to make bundleList = [] # List to hold metrics that shouldn't be saved noSaveBundleList = [] # Connect to the databse opsimdb = db.OpsimDatabaseV4(dbFile) if runName is None: runName = os.path.basename(dbFile).replace('_sqlite.db', '') # Fetch the proposal ID values from the database propids, propTags = opsimdb.fetchPropInfo() # Fetch the telescope location from config lat, lon, height = opsimdb.fetchLatLonHeight() # Add metadata regarding dithering/non-dithered. commonname = ''.join([a for a in lonCol if a in latCol]) if commonname == 'field': slicermetadata = ' (non-dithered)' else: slicermetadata = ' (%s)' % (commonname) # Construct a WFD SQL where clause so multiple propIDs can query by WFD: wfdWhere = opsimdb.createSQLWhere('WFD', propTags) print('#FYI: WFD "where" clause: %s' % (wfdWhere)) ddWhere = opsimdb.createSQLWhere('DD', propTags) print('#FYI: DD "where" clause: %s' % (ddWhere)) # Set up benchmark values, scaled to length of opsim run. runLength = opsimdb.fetchRunLength() if benchmark == 'requested': # Fetch design values for seeing/skybrightness/single visit depth. benchmarkVals = utils.scaleBenchmarks(runLength, benchmark='design') # Update nvisits with requested visits from config files. benchmarkVals['nvisits'] = opsimdb.fetchRequestedNvisits(propId=propTags['WFD']) # Calculate expected coadded depth. benchmarkVals['coaddedDepth'] = utils.calcCoaddedDepth(benchmarkVals['nvisits'], benchmarkVals['singleVisitDepth']) elif (benchmark == 'stretch') or (benchmark == 'design'): # Calculate benchmarks for stretch or design. benchmarkVals = utils.scaleBenchmarks(runLength, benchmark=benchmark) benchmarkVals['coaddedDepth'] = utils.calcCoaddedDepth(benchmarkVals['nvisits'], benchmarkVals['singleVisitDepth']) else: raise ValueError('Could not recognize benchmark value %s, use design, stretch or requested.' % (benchmark)) # Check that nvisits is not set to zero (for very short run length). for f in benchmarkVals['nvisits']: if benchmarkVals['nvisits'][f] == 0: print('Updating benchmark nvisits value in %s to be nonzero' % (f)) benchmarkVals['nvisits'][f] = 1 # Set values for min/max range of nvisits for All/WFD and DD plots. These are somewhat arbitrary. nvisitsRange = {} nvisitsRange['all'] = {'u': [20, 80], 'g': [50, 150], 'r': [100, 250], 'i': [100, 250], 'z': [100, 300], 'y': [100, 300]} nvisitsRange['DD'] = {'u': [6000, 10000], 'g': [2500, 5000], 'r': [5000, 8000], 'i': [5000, 8000], 'z': [7000, 10000], 'y': [5000, 8000]} # Scale these ranges for the runLength. scale = runLength / 10.0 for prop in nvisitsRange: for f in nvisitsRange[prop]: for i in [0, 1]: nvisitsRange[prop][f][i] = int(np.floor(nvisitsRange[prop][f][i] * scale)) # Filter list, and map of colors (for plots) to filters. filters = ['u', 'g', 'r', 'i', 'z', 'y'] colors = {'u': 'cyan', 'g': 'g', 'r': 'y', 'i': 'r', 'z': 'm', 'y': 'k'} filtorder = {'u': 1, 'g': 2, 'r': 3, 'i': 4, 'z': 5, 'y': 6} # Easy way to run through all fi # Set up a list of common summary stats commonSummary = [metrics.MeanMetric(), metrics.RobustRmsMetric(), metrics.MedianMetric(), metrics.PercentileMetric(metricName='25th%ile', percentile=25), metrics.PercentileMetric(metricName='75th%ile', percentile=75), metrics.MinMetric(), metrics.MaxMetric()] allStats = commonSummary # Set up some 'group' labels reqgroup = 'A: Required SRD metrics' depthgroup = 'B: Depth per filter' uniformitygroup = 'C: Uniformity' airmassgroup = 'D: Airmass distribution' seeinggroup = 'E: Seeing distribution' transgroup = 'F: Transients' sngroup = 'G: SN Ia' altAzGroup = 'H: Alt Az' rangeGroup = 'I: Range of Dates' intergroup = 'J: Inter-Night' phaseGroup = 'K: Max Phase Gap' NEOGroup = 'L: NEO Detection' # Set up an object to track the metricBundles that we want to combine into merged plots. mergedHistDict = {} # Set the histogram merge function. mergeFunc = plots.HealpixHistogram() keys = ['NVisits', 'coaddm5', 'NormEffTime', 'Minseeing', 'seeingAboveLimit', 'minAirmass', 'fracAboveAirmass'] for key in keys: mergedHistDict[key] = plots.PlotBundle(plotFunc=mergeFunc) ## # Calculate the fO metrics for all proposals and WFD only. order = 0 for prop in ('All prop', 'WFD only'): if prop == 'All prop': metadata = 'All Visits' + slicermetadata sqlconstraint = '' if prop == 'WFD only': metadata = 'WFD only' + slicermetadata sqlconstraint = '%s' % (wfdWhere) # Configure the count metric which is what is used for f0 slicer. m1 = metrics.CountMetric(col='observationStartMJD', metricName='fO') plotDict = {'xlabel': 'Number of Visits', 'Asky': benchmarkVals['Area'], 'Nvisit': benchmarkVals['nvisitsTotal'], 'xMin': 0, 'xMax': 1500} summaryMetrics = [metrics.fOArea(nside=nside, norm=False, metricName='fOArea: Nvisits (#)', Asky=benchmarkVals['Area'], Nvisit=benchmarkVals['nvisitsTotal']), metrics.fOArea(nside=nside, norm=True, metricName='fOArea: Nvisits/benchmark', Asky=benchmarkVals['Area'], Nvisit=benchmarkVals['nvisitsTotal']), metrics.fONv(nside=nside, norm=False, metricName='fONv: Area (sqdeg)', Asky=benchmarkVals['Area'], Nvisit=benchmarkVals['nvisitsTotal']), metrics.fONv(nside=nside, norm=True, metricName='fONv: Area/benchmark', Asky=benchmarkVals['Area'], Nvisit=benchmarkVals['nvisitsTotal'])] caption = 'The FO metric evaluates the overall efficiency of observing. ' caption += ('fOArea: Nvisits = %.1f sq degrees receive at least this many visits out of %d. ' % (benchmarkVals['Area'], benchmarkVals['nvisitsTotal'])) caption += ('fONv: Area = this many square degrees out of %.1f receive at least %d visits.' % (benchmarkVals['Area'], benchmarkVals['nvisitsTotal'])) displayDict = {'group': reqgroup, 'subgroup': 'F0', 'displayOrder': order, 'caption': caption} order += 1 slicer = slicers.HealpixSlicer(nside=nside, lonCol=lonCol, latCol=latCol) bundle = metricBundles.MetricBundle(m1, slicer, sqlconstraint, plotDict=plotDict, displayDict=displayDict, summaryMetrics=summaryMetrics, plotFuncs=[plots.FOPlot()], runName=runName, metadata=metadata) bundleList.append(bundle) ### # Calculate the Rapid Revisit Metrics. order = 0 metadata = 'All Visits' + slicermetadata sqlconstraint = '' dTmin = 40.0 # seconds dTmax = 30.0*60. # seconds minNvisit = 100 pixArea = float(hp.nside2pixarea(nside, degrees=True)) scale = pixArea * hp.nside2npix(nside) cutoff1 = 0.15 extraStats1 = [metrics.FracBelowMetric(cutoff=cutoff1, scale=scale, metricName='Area (sq deg)')] extraStats1.extend(commonSummary) slicer = slicers.HealpixSlicer(nside=nside, lonCol=lonCol, latCol=latCol) m1 = metrics.RapidRevisitMetric(metricName='RapidRevisitUniformity', dTmin=dTmin / 60.0 / 60.0 / 24.0, dTmax=dTmax / 60.0 / 60.0 / 24.0, minNvisits=minNvisit) plotDict = {'xMin': 0, 'xMax': 1} summaryStats = extraStats1 caption = 'Deviation from uniformity for short revisit timescales, between %s and %s seconds, ' % ( dTmin, dTmax) caption += 'for pointings with at least %d visits in this time range. ' % (minNvisit) caption += 'Summary statistic "Area" below indicates the area on the sky which has a ' caption += 'deviation from uniformity of < %.2f.' % (cutoff1) displayDict = {'group': reqgroup, 'subgroup': 'Rapid Revisit', 'displayOrder': order, 'caption': caption} bundle = metricBundles.MetricBundle(m1, slicer, sqlconstraint, plotDict=plotDict, displayDict=displayDict, summaryMetrics=summaryStats, runName=runName, metadata=metadata) bundleList.append(bundle) order += 1 dTmax = dTmax/60.0 # need time in minutes for Nrevisits metric m2 = metrics.NRevisitsMetric(dT=dTmax) plotDict = {'xMin': 0.1, 'xMax': 2000, 'logScale': True} cutoff2 = 800 extraStats2 = [metrics.FracAboveMetric(cutoff=cutoff2, scale=scale, metricName='Area (sq deg)')] extraStats2.extend(commonSummary) caption = 'Number of consecutive visits with return times faster than %.1f minutes, ' % (dTmax) caption += 'in any filter, all proposals. ' caption += 'Summary statistic "Area" below indicates the area on the sky which has more than ' caption += '%d revisits within this time window.' % (cutoff2) summaryStats = extraStats2 displayDict = {'group': reqgroup, 'subgroup': 'Rapid Revisit', 'displayOrder': order, 'caption': caption} bundle = metricBundles.MetricBundle(m2, slicer, sqlconstraint, plotDict=plotDict, displayDict=displayDict, summaryMetrics=summaryStats, runName=runName, metadata=metadata) bundleList.append(bundle) order += 1 m3 = metrics.NRevisitsMetric(dT=dTmax, normed=True) plotDict = {'xMin': 0, 'xMax': 1, 'cbarFormat': '%.1f'} cutoff3 = 0.6 extraStats3 = [metrics.FracAboveMetric(cutoff=cutoff3, scale=scale, metricName='Area (sq deg)')] extraStats3.extend(commonSummary) summaryStats = extraStats3 caption = 'Fraction of total visits where consecutive visits have return times faster ' caption += 'than %.1f minutes, in any filter, all proposals. ' % (dTmax) caption += 'Summary statistic "Area" below indicates the area on the sky which has more ' caption += 'than %d revisits within this time window.' % (cutoff3) displayDict = {'group': reqgroup, 'subgroup': 'Rapid Revisit', 'displayOrder': order, 'caption': caption} bundle = metricBundles.MetricBundle(m3, slicer, sqlconstraint, plotDict=plotDict, displayDict=displayDict, summaryMetrics=summaryStats, runName=runName, metadata=metadata) bundleList.append(bundle) order += 1 # And add a histogram of the time between quick revisits. binMin = 0 binMax = 120. binsize = 3. bins_metric = np.arange(binMin / 60.0 / 24.0, (binMax + binsize) / 60. / 24., binsize / 60. / 24.) bins_plot = bins_metric * 24.0 * 60.0 m1 = metrics.TgapsMetric(bins=bins_metric, metricName='dT visits') plotDict = {'bins': bins_plot, 'xlabel': 'dT (minutes)'} caption = ('Histogram of the time between consecutive revisits (<%.1f minutes), over entire sky.' % (binMax)) displayDict = {'group': reqgroup, 'subgroup': 'Rapid Revisit', 'order': order, 'caption': caption} slicer = slicers.HealpixSlicer(nside=nside, lonCol=lonCol, latCol=latCol) plotFunc = plots.SummaryHistogram() bundle = metricBundles.MetricBundle(m1, slicer, sqlconstraint, plotDict=plotDict, displayDict=displayDict, runName=runName, metadata=metadata, plotFuncs=[plotFunc]) bundleList.append(bundle) order += 1 ## # Trigonometric parallax and proper motion @ r=20 and r=24 slicer = slicers.HealpixSlicer(nside=nside, lonCol=lonCol, latCol=latCol) sqlconstraint = '' order = 0 metric = metrics.ParallaxMetric(metricName='Parallax 20', rmag=20, seeingCol=seeingCol) summaryStats = allStats plotDict = {'cbarFormat': '%.1f', 'xMin': 0, 'xMax': 3} displayDict = {'group': reqgroup, 'subgroup': 'Parallax', 'order': order, 'caption': 'Parallax precision at r=20. (without refraction).'} bundle = metricBundles.MetricBundle(metric, slicer, sqlconstraint, plotDict=plotDict, displayDict=displayDict, summaryMetrics=summaryStats, runName=runName, metadata=metadata) bundleList.append(bundle) order += 1 metric = metrics.ParallaxMetric(metricName='Parallax 24', rmag=24, seeingCol=seeingCol) plotDict = {'cbarFormat': '%.1f', 'xMin': 0, 'xMax': 10} displayDict = {'group': reqgroup, 'subgroup': 'Parallax', 'order': order, 'caption': 'Parallax precision at r=24. (without refraction).'} bundle = metricBundles.MetricBundle(metric, slicer, sqlconstraint, plotDict=plotDict, displayDict=displayDict, summaryMetrics=summaryStats, runName=runName, metadata=metadata) bundleList.append(bundle) order += 1 metric = metrics.ParallaxMetric(metricName='Parallax Normed', rmag=24, normalize=True, seeingCol=seeingCol) plotDict = {'xMin': 0.5, 'xMax': 1.0} displayDict = {'group': reqgroup, 'subgroup': 'Parallax', 'order': order, 'caption': 'Normalized parallax (normalized to optimum observation cadence, 1=optimal).'} bundle = metricBundles.MetricBundle(metric, slicer, sqlconstraint, plotDict=plotDict, displayDict=displayDict, summaryMetrics=summaryStats, runName=runName, metadata=metadata) bundleList.append(bundle) order += 1 metric = metrics.ParallaxCoverageMetric(metricName='Parallax Coverage 20', rmag=20, seeingCol=seeingCol) plotDict = {} caption = "Parallax factor coverage for an r=20 star (0 is bad, 0.5-1 is good). " caption += "One expects the parallax factor coverage to vary because stars on the ecliptic " caption += "can be observed when they have no parallax offset while stars at the pole are always " caption += "offset by the full parallax offset.""" displayDict = {'group': reqgroup, 'subgroup': 'Parallax', 'order': order, 'caption': caption} bundle = metricBundles.MetricBundle(metric, slicer, sqlconstraint, plotDict=plotDict, displayDict=displayDict, summaryMetrics=summaryStats, runName=runName, metadata=metadata) bundleList.append(bundle) order += 1 metric = metrics.ParallaxCoverageMetric(metricName='Parallax Coverage 24', rmag=24, seeingCol=seeingCol) plotDict = {} caption = "Parallax factor coverage for an r=24 star (0 is bad, 0.5-1 is good). " caption += "One expects the parallax factor coverage to vary because stars on the ecliptic " caption += "can be observed when they have no parallax offset while stars at the pole are always " caption += "offset by the full parallax offset.""" displayDict = {'group': reqgroup, 'subgroup': 'Parallax', 'order': order, 'caption': caption} bundle = metricBundles.MetricBundle(metric, slicer, sqlconstraint, plotDict=plotDict, displayDict=displayDict, summaryMetrics=summaryStats, runName=runName, metadata=metadata) bundleList.append(bundle) order += 1 metric = metrics.ParallaxDcrDegenMetric(metricName='Parallax-DCR degeneracy 20', rmag=20, seeingCol=seeingCol) plotDict = {} caption = 'Correlation between parallax offset magnitude and hour angle an r=20 star.' caption += ' (0 is good, near -1 or 1 is bad).' displayDict = {'group': reqgroup, 'subgroup': 'Parallax', 'order': order, 'caption': caption} bundle = metricBundles.MetricBundle(metric, slicer, sqlconstraint, plotDict=plotDict, displayDict=displayDict, summaryMetrics=summaryStats, runName=runName, metadata=metadata) bundleList.append(bundle) order += 1 metric = metrics.ParallaxDcrDegenMetric(metricName='Parallax-DCR degeneracy 24', rmag=24, seeingCol=seeingCol) plotDict = {} caption = 'Correlation between parallax offset magnitude and hour angle an r=24 star.' caption += ' (0 is good, near -1 or 1 is bad).' displayDict = {'group': reqgroup, 'subgroup': 'Parallax', 'order': order, 'caption': caption} bundle = metricBundles.MetricBundle(metric, slicer, sqlconstraint, plotDict=plotDict, displayDict=displayDict, summaryMetrics=summaryStats, runName=runName, metadata=metadata) bundleList.append(bundle) order += 1 metric = metrics.ProperMotionMetric(metricName='Proper Motion 20', rmag=20, seeingCol=seeingCol) summaryStats = allStats plotDict = {'xMin': 0, 'xMax': 3} displayDict = {'group': reqgroup, 'subgroup': 'Proper Motion', 'order': order, 'caption': 'Proper Motion precision at r=20.'} bundle = metricBundles.MetricBundle(metric, slicer, sqlconstraint, plotDict=plotDict, displayDict=displayDict, summaryMetrics=summaryStats, runName=runName, metadata=metadata) bundleList.append(bundle) order += 1 metric = metrics.ProperMotionMetric(rmag=24, metricName='Proper Motion 24', seeingCol=seeingCol) summaryStats = allStats plotDict = {'xMin': 0, 'xMax': 10} displayDict = {'group': reqgroup, 'subgroup': 'Proper Motion', 'order': order, 'caption': 'Proper Motion precision at r=24.'} bundle = metricBundles.MetricBundle(metric, slicer, sqlconstraint, plotDict=plotDict, displayDict=displayDict, summaryMetrics=summaryStats, runName=runName, metadata=metadata) bundleList.append(bundle) order += 1 metric = metrics.ProperMotionMetric(rmag=24, normalize=True, metricName='Proper Motion Normed', seeingCol=seeingCol) plotDict = {'xMin': 0.2, 'xMax': 0.7} caption = 'Normalized proper motion at r=24. ' caption += '(normalized to optimum observation cadence - start/end. 1=optimal).' displayDict = {'group': reqgroup, 'subgroup': 'Proper Motion', 'order': order, 'caption': caption} bundle = metricBundles.MetricBundle(metric, slicer, sqlconstraint, plotDict=plotDict, displayDict=displayDict, summaryMetrics=summaryStats, runName=runName, metadata=metadata) bundleList.append(bundle) order += 1 ## # Calculate the time uniformity in each filter, for each year. order = 0 slicer = slicers.HealpixSlicer(nside=nside, lonCol=lonCol, latCol=latCol) plotFuncs = [plots.TwoDMap()] step = 0.5 bins = np.arange(0, 365.25 * 10 + 40, 40) - step metric = metrics.AccumulateUniformityMetric(bins=bins) plotDict = {'xlabel': 'Night (days)', 'xextent': [bins.min( ) + step, bins.max() + step], 'cbarTitle': 'Uniformity'} for f in filters: sqlconstraint = 'filter = "%s"' % (f) caption = 'Deviation from uniformity in %s band. ' % f caption += 'Northern Healpixels are at the top of the image.' caption += '(0=perfectly uniform, 1=perfectly nonuniform).' displayDict = {'group': uniformitygroup, 'subgroup': 'per night', 'order': filtorder[f], 'caption': caption} metadata = '%s band' % (f) + slicermetadata bundle = metricBundles.MetricBundle(metric, slicer, sqlconstraint, plotDict=plotDict, displayDict=displayDict, runName=runName, metadata=metadata, plotFuncs=plotFuncs) noSaveBundleList.append(bundle) ## # Depth metrics. slicer = slicers.HealpixSlicer(nside=nside, lonCol=lonCol, latCol=latCol) for f in filters: propCaption = '%s band, all proposals %s' % (f, slicermetadata) sqlconstraint = 'filter = "%s"' % (f) metadata = '%s band' % (f) + slicermetadata # Number of visits. metric = metrics.CountMetric(col='observationStartMJD', metricName='NVisits') plotDict = {'xlabel': 'Number of visits', 'xMin': nvisitsRange['all'][f][0], 'xMax': nvisitsRange['all'][f][1], 'colorMin': nvisitsRange['all'][f][0], 'colorMax': nvisitsRange['all'][f][1], 'binsize': 5, 'logScale': True, 'nTicks': 4, 'colorMin': 1} summaryStats = allStats displayDict = {'group': depthgroup, 'subgroup': 'Nvisits', 'order': filtorder[f], 'caption': 'Number of visits in filter %s, %s.' % (f, propCaption)} histMerge = {'color': colors[f], 'label': '%s' % (f), 'binsize': 5, 'xMin': nvisitsRange['all'][f][0], 'xMax': nvisitsRange['all'][f][1], 'legendloc': 'upper right'} bundle = metricBundles.MetricBundle(metric, slicer, sqlconstraint, plotDict=plotDict, displayDict=displayDict, runName=runName, metadata=metadata, summaryMetrics=summaryStats) mergedHistDict['NVisits'].addBundle(bundle, plotDict=histMerge) bundleList.append(bundle) # Coadded depth. metric = metrics.Coaddm5Metric() plotDict = {'zp': benchmarkVals['coaddedDepth'][f], 'xMin': -0.8, 'xMax': 0.8, 'xlabel': 'coadded m5 - %.1f' % benchmarkVals['coaddedDepth'][f]} summaryStats = allStats histMerge = {'legendloc': 'upper right', 'color': colors[f], 'label': '%s' % f, 'binsize': .02, 'xlabel': 'coadded m5 - benchmark value'} caption = ('Coadded depth in filter %s, with %s value subtracted (%.1f), %s. ' % (f, benchmark, benchmarkVals['coaddedDepth'][f], propCaption)) caption += 'More positive numbers indicate fainter limiting magnitudes.' displayDict = {'group': depthgroup, 'subgroup': 'Coadded Depth', 'order': filtorder[f], 'caption': caption} bundle = metricBundles.MetricBundle(metric, slicer, sqlconstraint, plotDict=plotDict, displayDict=displayDict, runName=runName, metadata=metadata, summaryMetrics=summaryStats) mergedHistDict['coaddm5'].addBundle(bundle, plotDict=histMerge) bundleList.append(bundle) # Effective time. metric = metrics.TeffMetric(metricName='Normalized Effective Time', normed=True, fiducialDepth=benchmarkVals['singleVisitDepth']) plotDict = {'xMin': 0.1, 'xMax': 1.1} summaryStats = allStats histMerge = {'legendLoc': 'upper right', 'color': colors[f], 'label': '%s' % f, 'binsize': 0.02} caption = ('"Time Effective" in filter %s, calculated with fiducial single-visit depth of %s mag. ' % (f, benchmarkVals['singleVisitDepth'][f])) caption += 'Normalized by the fiducial time effective, if every observation was at ' caption += 'the fiducial depth.' displayDict = {'group': depthgroup, 'subgroup': 'Time Eff.', 'order': filtorder[f], 'caption': caption} bundle = metricBundles.MetricBundle(metric, slicer, sqlconstraint, plotDict=plotDict, displayDict=displayDict, runName=runName, metadata=metadata, summaryMetrics=summaryStats) mergedHistDict['NormEffTime'].addBundle(bundle, plotDict=histMerge) bundleList.append(bundle) # Put in a z=0.5 Type Ia SN, based on Cambridge 2015 workshop notebook. # Check for 1) detection in any band, 2) detection on the rise in any band, # 3) good characterization peaks = {'uPeak': 25.9, 'gPeak': 23.6, 'rPeak': 22.6, 'iPeak': 22.7, 'zPeak': 22.7, 'yPeak': 22.8} peakTime = 15. transDuration = peakTime + 30. # Days metric = metrics.TransientMetric(riseSlope=-2. / peakTime, declineSlope=1.4 / 30.0, transDuration=transDuration, peakTime=peakTime, surveyDuration=runLength, metricName='SNDetection', **peaks) caption = 'Fraction of z=0.5 type Ia SN that are detected in any filter' displayDict = {'group': transgroup, 'subgroup': 'Detected', 'caption': caption} sqlconstraint = '' metadata = '' + slicermetadata plotDict = {} bundle = metricBundles.MetricBundle(metric, slicer, sqlconstraint, plotDict=plotDict, displayDict=displayDict, runName=runName, metadata=metadata) bundleList.append(bundle) metric = metrics.TransientMetric(riseSlope=-2. / peakTime, declineSlope=1.4 / 30.0, transDuration=transDuration, peakTime=peakTime, surveyDuration=runLength, nPrePeak=1, metricName='SNAlert', **peaks) caption = 'Fraction of z=0.5 type Ia SN that are detected pre-peak in any filter' displayDict = {'group': transgroup, 'subgroup': 'Detected on the rise', 'caption': caption} plotDict = {} bundle = metricBundles.MetricBundle(metric, slicer, sqlconstraint, plotDict=plotDict, displayDict=displayDict, runName=runName, metadata=metadata) bundleList.append(bundle) metric = metrics.TransientMetric(riseSlope=-2. / peakTime, declineSlope=1.4 / 30., transDuration=transDuration, peakTime=peakTime, surveyDuration=runLength, metricName='SNLots', nFilters=3, nPrePeak=3, nPerLC=2, **peaks) caption = 'Fraction of z=0.5 type Ia SN that are observed 6 times, 3 pre-peak, ' caption += '3 post-peak, with observations in 3 filters' displayDict = {'group': transgroup, 'subgroup': 'Well observed', 'caption': caption} sqlconstraint = 'filter="r" or filter="g" or filter="i" or filter="z" ' plotDict = {} bundle = metricBundles.MetricBundle(metric, slicer, sqlconstraint, plotDict=plotDict, displayDict=displayDict, runName=runName, metadata=metadata) bundleList.append(bundle) # Good seeing in r/i band metrics, including in first/second years. order = 0 for tcolor, tlabel, timespan in zip(['k', 'g', 'r'], ['10 years', '1 year', '2 years'], ['', ' and night<=365', ' and night<=730']): order += 1 for f in (['r', 'i']): sqlconstraint = 'filter = "%s" %s' % (f, timespan) propCaption = '%s band, all proposals %s, over %s.' % (f, slicermetadata, tlabel) metadata = '%s band, %s' % (f, tlabel) + slicermetadata seeing_limit = 0.7 airmass_limit = 1.2 metric = metrics.MinMetric(col=seeingCol) summaryStats = allStats plotDict = {'xMin': 0.35, 'xMax': 1.5, 'color': tcolor} displayDict = {'group': seeinggroup, 'subgroup': 'Best Seeing', 'order': filtorder[f] * 100 + order, 'caption': 'Minimum FWHMgeom values in %s.' % (propCaption)} histMerge = {'label': '%s %s' % (f, tlabel), 'color': tcolor, 'binsize': 0.03, 'xMin': 0.35, 'xMax': 1.5, 'legendloc': 'upper right'} bundle = metricBundles.MetricBundle(metric, slicer, sqlconstraint, plotDict=plotDict, displayDict=displayDict, runName=runName, metadata=metadata, summaryMetrics=summaryStats) mergedHistDict['Minseeing'].addBundle(bundle, plotDict=histMerge) bundleList.append(bundle) metric = metrics.FracAboveMetric(col=seeingCol, cutoff=seeing_limit) summaryStats = allStats plotDict = {'xMin': 0, 'xMax': 1.1, 'color': tcolor} displayDict = {'group': seeinggroup, 'subgroup': 'Good seeing fraction', 'order': filtorder[f] * 100 + order, 'caption': 'Fraction of total images with FWHMgeom worse than %.1f, in %s' % (seeing_limit, propCaption)} histMerge = {'color': tcolor, 'label': '%s %s' % (f, tlabel), 'binsize': 0.05, 'legendloc': 'upper right'} bundle = metricBundles.MetricBundle(metric, slicer, sqlconstraint, plotDict=plotDict, displayDict=displayDict, runName=runName, metadata=metadata, summaryMetrics=summaryStats) mergedHistDict['seeingAboveLimit'].addBundle(bundle, plotDict=histMerge) bundleList.append(bundle) metric = metrics.MinMetric(col='airmass') plotDict = {'xMin': 1, 'xMax': 1.5, 'color': tcolor} summaryStats = allStats displayDict = {'group': airmassgroup, 'subgroup': 'Best Airmass', 'order': filtorder[f] * 100 + order, 'caption': 'Minimum airmass in %s.' % (propCaption)} histMerge = {'color': tcolor, 'label': '%s %s' % (f, tlabel), 'binsize': 0.03, 'legendloc': 'upper right'} bundle = metricBundles.MetricBundle(metric, slicer, sqlconstraint, plotDict=plotDict, displayDict=displayDict, runName=runName, metadata=metadata, summaryMetrics=summaryStats) mergedHistDict['minAirmass'].addBundle(bundle, plotDict=histMerge) bundleList.append(bundle) metric = metrics.FracAboveMetric(col='airmass', cutoff=airmass_limit) plotDict = {'xMin': 0, 'xMax': 1, 'color': tcolor} summaryStats = allStats displayDict = {'group': airmassgroup, 'subgroup': 'Low airmass fraction', 'order': filtorder[f] * 100 + order, 'caption': 'Fraction of total images with airmass higher than %.2f, in %s' % (airmass_limit, propCaption)} histMerge = {'color': tcolor, 'label': '%s %s' % ( f, tlabel), 'binsize': 0.05, 'legendloc': 'upper right'} bundle = metricBundles.MetricBundle(metric, slicer, sqlconstraint, plotDict=plotDict, displayDict=displayDict, runName=runName, metadata=metadata, summaryMetrics=summaryStats) mergedHistDict['fracAboveAirmass'].addBundle(bundle, plotDict=histMerge) bundleList.append(bundle) # SNe metrics from UK workshop. peaks = {'uPeak': 25.9, 'gPeak': 23.6, 'rPeak': 22.6, 'iPeak': 22.7, 'zPeak': 22.7, 'yPeak': 22.8} peakTime = 15. transDuration = peakTime + 30. # Days metric = metrics.TransientMetric(riseSlope=-2. / peakTime, declineSlope=1.4 / 30.0, transDuration=transDuration, peakTime=peakTime, surveyDuration=runLength, metricName='SNDetection', **peaks) caption = 'Fraction of z=0.5 type Ia SN that are detected at any point in their light curve in any filter' displayDict = {'group': sngroup, 'subgroup': 'Detected', 'caption': caption} sqlconstraint = '' plotDict = {} bundle = metricBundles.MetricBundle(metric, slicer, sqlconstraint, plotDict=plotDict, displayDict=displayDict, runName=runName) bundleList.append(bundle) metric = metrics.TransientMetric(riseSlope=-2. / peakTime, declineSlope=1.4 / 30.0, transDuration=transDuration, peakTime=peakTime, surveyDuration=runLength, nPrePeak=1, metricName='SNAlert', **peaks) caption = 'Fraction of z=0.5 type Ia SN that are detected pre-peak in any filter' displayDict = {'group': sngroup, 'subgroup': 'Detected on the rise', 'caption': caption} plotDict = {} bundle = metricBundles.MetricBundle(metric, slicer, sqlconstraint, plotDict=plotDict, displayDict=displayDict, runName=runName) bundleList.append(bundle) metric = metrics.TransientMetric(riseSlope=-2. / peakTime, declineSlope=1.4 / 30., transDuration=transDuration, peakTime=peakTime, surveyDuration=runLength, metricName='SNLots', nFilters=3, nPrePeak=3, nPerLC=2, **peaks) caption = 'Fraction of z=0.5 type Ia SN that are observed 6 times, 3 pre-peak, ' caption += '3 post-peak, with observations in 3 filters' displayDict = {'group': sngroup, 'subgroup': 'Well observed', 'caption': caption} sqlconstraint = 'filter="r" or filter="g" or filter="i" or filter="z" ' plotDict = {} bundle = metricBundles.MetricBundle(metric, slicer, sqlconstraint, plotDict=plotDict, displayDict=displayDict, runName=runName) bundleList.append(bundle) propIDOrderDict = {} orderVal = 100 for propID in propids: propIDOrderDict[propID] = orderVal orderVal += 100 # Full range of dates: metric = metrics.FullRangeMetric(col='observationStartMJD') plotFuncs = [plots.HealpixSkyMap(), plots.HealpixHistogram()] caption = 'Time span of survey.' sqlconstraint = '' plotDict = {} displayDict = {'group': rangeGroup, 'caption': caption} bundle = metricBundles.MetricBundle(metric, slicer, sqlconstraint, plotDict=plotDict, displayDict=displayDict, runName=runName) bundleList.append(bundle) for f in filters: for propid in propids: displayDict = {'group': rangeGroup, 'subgroup': propids[propid], 'caption': caption, 'order': filtorder[f]} md = '%s, %s' % (f, propids[propid]) sql = 'filter="%s" and proposalId=%i' % (f, propid) bundle = metricBundles.MetricBundle(metric, slicer, sql, plotDict=plotDict, metadata=md, plotFuncs=plotFuncs, displayDict=displayDict, runName=runName) bundleList.append(bundle) # Alt az plots slicer = slicers.HealpixSlicer(nside=64, latCol='zenithDistance', lonCol='azimuth', useCache=False) metric = metrics.CountMetric('observationStartMJD', metricName='Nvisits as function of Alt/Az') plotDict = {} plotFuncs = [plots.LambertSkyMap()] displayDict = {'group': altAzGroup, 'caption': 'Alt Az pointing distribution'} for f in filters: for propid in propids: displayDict = {'group': altAzGroup, 'subgroup': propids[propid], 'caption': 'Alt Az pointing distribution', 'order': filtorder[f]} md = '%s, %s' % (f, propids[propid]) sql = 'filter="%s" and proposalId=%i' % (f, propid) bundle = metricBundles.MetricBundle(metric, slicer, sql, plotDict=plotDict, plotFuncs=plotFuncs, metadata=md, displayDict=displayDict, runName=runName) bundleList.append(bundle) sql = '' md = 'all observations' displayDict = {'group': altAzGroup, 'subgroup': 'All Observations', 'caption': 'Alt Az pointing distribution'} bundle = metricBundles.MetricBundle(metric, slicer, sql, plotDict=plotDict, plotFuncs=plotFuncs, metadata=md, displayDict=displayDict, runName=runName) bundleList.append(bundle) # Median inter-night gap (each and all filters) slicer = slicers.HealpixSlicer(nside=nside, lonCol=lonCol, latCol=latCol) metric = metrics.InterNightGapsMetric(metricName='Median Inter-Night Gap') sqls = ['filter = "%s"' % f for f in filters] orders = [filtorder[f] for f in filters] orders.append(0) sqls.append('') for sql, order in zip(sqls, orders): displayDict = {'group': intergroup, 'subgroup': 'Median Gap', 'caption': 'Median gap between days', 'order': order} bundle = metricBundles.MetricBundle(metric, slicer, sql, displayDict=displayDict, runName=runName) bundleList.append(bundle) # Max inter-night gap in r and all bands dslicer = slicers.HealpixSlicer(nside=nside, lonCol='ditheredRA', latCol='ditheredDec') metric = metrics.InterNightGapsMetric(metricName='Max Inter-Night Gap', reduceFunc=np.max) plotDict = {'percentileClip': 95.} for sql, order in zip(sqls, orders): displayDict = {'group': intergroup, 'subgroup': 'Max Gap', 'caption': 'Max gap between nights', 'order': order} bundle = metricBundles.MetricBundle(metric, dslicer, sql, displayDict=displayDict, plotDict=plotDict, runName=runName) bundleList.append(bundle) # largest phase gap for periods periods = [0.1, 1.0, 10., 100.] sqls = {'u': 'filter = "u"', 'r': 'filter="r"', 'g,r,i,z': 'filter="g" or filter="r" or filter="i" or filter="z"', 'all': ''} for sql in sqls: for period in periods: displayDict = {'group': phaseGroup, 'subgroup': 'period=%.2f days, filter=%s' % (period, sql), 'caption': 'Maximum phase gaps'} metric = metrics.PhaseGapMetric(nPeriods=1, periodMin=period, periodMax=period, metricName='PhaseGap, %.1f' % period) bundle = metricBundles.MetricBundle(metric, slicer, sqls[sql], displayDict=displayDict, runName=runName) bundleList.append(bundle) # NEO XY plots slicer = slicers.UniSlicer() metric = metrics.PassMetric(metricName='NEODistances') stacker = stackers.NEODistStacker() stacker2 = stackers.EclipticStacker() for f in filters: plotFunc = plots.NeoDistancePlotter(eclipMax=10., eclipMin=-10.) caption = 'Observations within 10 degrees of the ecliptic. Distance an H=22 NEO would be detected' displayDict = {'group': NEOGroup, 'subgroup': 'xy', 'order': filtorder[f], 'caption': caption} plotDict = {} sqlconstraint = 'filter = "%s"' % (f) bundle = metricBundles.MetricBundle(metric, slicer, sqlconstraint, displayDict=displayDict, stackerList=[stacker, stacker2], plotDict=plotDict, plotFuncs=[plotFunc]) noSaveBundleList.append(bundle) # Solar elongation sqls = ['filter = "%s"' % f for f in filters] orders = [filtorder[f] for f in filters] sqls.append('') orders.append(0) for sql, order in zip(sqls, orders): plotFuncs = [plots.HealpixSkyMap(), plots.HealpixHistogram()] displayDict = {'group': NEOGroup, 'subgroup': 'Solar Elongation', 'caption': 'Median solar elongation in degrees', 'order': order} metric = metrics.MedianMetric('solarElong') slicer = slicers.HealpixSlicer(nside=nside, lonCol=lonCol, latCol=latCol) bundle = metricBundles.MetricBundle(metric, slicer, sql, displayDict=displayDict, plotFuncs=plotFuncs) bundleList.append(bundle) plotFuncs = [plots.HealpixSkyMap(), plots.HealpixHistogram()] displayDict = {'group': NEOGroup, 'subgroup': 'Solar Elongation', 'caption': 'Minimum solar elongation in degrees', 'order': order} metric = metrics.MinMetric('solarElong') slicer = slicers.HealpixSlicer(nside=nside, lonCol=lonCol, latCol=latCol) bundle = metricBundles.MetricBundle(metric, slicer, sql, displayDict=displayDict, plotFuncs=plotFuncs) bundleList.append(bundle) return (metricBundles.makeBundlesDictFromList(bundleList), mergedHistDict, metricBundles.makeBundlesDictFromList(noSaveBundleList))
def __call__(self, metricValue, slicer, userPlotDict, fignum=None): """ Parameters ---------- metricValue : numpy.ma.MaskedArray The metric values calculated with the 'Count' metric and a healpix slicer. slicer : lsst.sims.maf.slicers.HealpixSlicer userPlotDict: dict Dictionary of plot parameters set by user (overrides default values). Note that Asky and Nvisits values set here and in the slicer should be consistent, for plot labels and summary statistic values to be consistent. fignum : int Matplotlib figure number to use (default = None, starts new figure). Returns ------- int Matplotlib figure number used to create the plot. """ if not hasattr(slicer, 'nside'): raise ValueError('FOPlot to be used with healpix or healpix derived slicers.') fig = plt.figure(fignum) plotDict = {} plotDict.update(self.defaultPlotDict) plotDict.update(userPlotDict) if plotDict['scale'] is None: plotDict['scale'] = (hp.nside2pixarea(slicer.nside, degrees=True) / 1000.0) # Expect metricValue to be something like number of visits cumulativeArea = np.arange(1, metricValue.compressed().size + 1)[::-1] * plotDict['scale'] plt.plot(np.sort(metricValue.compressed()), cumulativeArea, 'k-', linewidth=plotDict['linewidth'], zorder=0) # This is breaking the rules and calculating the summary stats in two places. # Could just calculate summary stats and pass in labels. rarr = np.array(list(zip(metricValue.compressed())), dtype=[('fO', metricValue.dtype)]) fOArea = metrics.fOArea(col='fO', Asky=plotDict['Asky'], norm=False, nside=slicer.nside).run(rarr) fONv = metrics.fONv(col='fO', Nvisit=plotDict['Nvisits'], norm=False, nside=slicer.nside).run(rarr) plt.axvline(x=plotDict['Nvisits'], linewidth=plotDict['reflinewidth'], color='b') plt.axhline(y=plotDict['Asky'] / 1000., linewidth=plotDict['reflinewidth'], color='r') # Add lines for Nvis_median and fOArea: note if these are -666 (badval), # the default xMin/yMin values will just leave them off the edges of the plot. Nvis_median = fONv['value'][np.where(fONv['name'] == 'MedianNvis')] plt.axhline(y=Nvis_median / 1000., linewidth=plotDict['reflinewidth'], color='b', alpha=.5, label=r'f$_0$ Median Nvisits=%.3g' % Nvis_median) plt.axvline(x=fOArea, linewidth=plotDict['reflinewidth'], color='r', alpha=.5, label='f$_0$ Area=%.3g' % fOArea) plt.legend(loc='lower left', fontsize='small', numpoints=1) plt.xlabel(plotDict['xlabel']) plt.ylabel(plotDict['ylabel']) plt.title(plotDict['title']) xMin = plotDict['xMin'] xMax = plotDict['xMax'] yMin = plotDict['yMin'] yMax = plotDict['yMax'] if (xMin is not None) or (xMax is not None): plt.xlim([xMin, xMax]) if (yMin is not None) or (yMax is not None): plt.ylim([yMin, yMax]) return fig.number
def fOBatch(colmap=None, runName='opsim', extraSql=None, extraMetadata=None, nside=64, benchmarkArea=18000, benchmarkNvisits=825, ditherStacker=None, ditherkwargs=None): """Metrics for calculating fO. Parameters ---------- colmap : dict or None, opt A dictionary with a mapping of column names. Default will use OpsimV4 column names. runName : str, opt The name of the simulated survey. Default is "opsim". nside : int, opt Nside for the healpix slicer. Default 64. extraSql : str or None, opt Additional sql constraint to apply to all metrics. extraMetadata : str or None, opt Additional metadata to apply to all results. ditherStacker: str or lsst.sims.maf.stackers.BaseDitherStacker Optional dither stacker to use to define ra/dec columns. ditherkwargs: dict, opt Optional dictionary of kwargs for the dither stacker. Returns ------- metricBundleDict """ if colmap is None: colmap = ColMapDict('opsimV4') bundleList = [] sql = '' metadata = 'All visits' # Add additional sql constraint (such as wfdWhere) and metadata, if provided. if (extraSql is not None) and (len(extraSql) > 0): sql = extraSql if extraMetadata is None: metadata = extraSql.replace('filter =', '').replace('filter=', '') metadata = metadata.replace('"', '').replace("'", '') if extraMetadata is not None: metadata = extraMetadata subgroup = metadata raCol, decCol, degrees, ditherStacker, ditherMeta = radecCols( ditherStacker, colmap, ditherkwargs) # Don't want dither info in subgroup (too long), but do want it in bundle name. metadata = combineMetadata(metadata, ditherMeta) # Set up fO metric. slicer = slicers.HealpixSlicer(nside=nside, lonCol=raCol, latCol=decCol, latLonDeg=degrees) displayDict = {'group': 'FO metrics', 'subgroup': subgroup, 'order': 0} # Configure the count metric which is what is used for f0 slicer. metric = metrics.CountMetric(col=colmap['mjd'], metricName='fO') plotDict = { 'xlabel': 'Number of Visits', 'Asky': benchmarkArea, 'Nvisit': benchmarkNvisits, 'xMin': 0, 'xMax': 1500 } summaryMetrics = [ metrics.fOArea(nside=nside, norm=False, metricName='fOArea', Asky=benchmarkArea, Nvisit=benchmarkNvisits), metrics.fOArea(nside=nside, norm=True, metricName='fOArea/benchmark', Asky=benchmarkArea, Nvisit=benchmarkNvisits), metrics.fONv(nside=nside, norm=False, metricName='fONv', Asky=benchmarkArea, Nvisit=benchmarkNvisits), metrics.fONv(nside=nside, norm=True, metricName='fONv/benchmark', Asky=benchmarkArea, Nvisit=benchmarkNvisits) ] caption = 'The FO metric evaluates the overall efficiency of observing. ' caption += ( 'foNv: out of %.2f sq degrees, the area receives at least X and a median of Y visits ' '(out of %d, if compared to benchmark). ' % (benchmarkArea, benchmarkNvisits)) caption += ('fOArea: this many sq deg (out of %.2f sq deg if compared ' 'to benchmark) receives at least %d visits. ' % (benchmarkArea, benchmarkNvisits)) displayDict['caption'] = caption bundle = mb.MetricBundle(metric, slicer, sql, plotDict=plotDict, stackerList=[ditherStacker], displayDict=displayDict, summaryMetrics=summaryMetrics, plotFuncs=[plots.FOPlot()], metadata=metadata) bundleList.append(bundle) # Set the runName for all bundles and return the bundleDict. for b in bundleList: b.setRunName(runName) return mb.makeBundlesDictFromList(bundleList)
def __call__(self, metricValue, slicer, userPlotDict, fignum=None): """ Parameters ---------- metricValue : numpy.ma.MaskedArray The metric values calculated with the 'Count' metric and a healpix slicer. slicer : lsst.sims.maf.slicers.HealpixSlicer userPlotDict: dict Dictionary of plot parameters set by user (overrides default values). Note that Asky and Nvisits values set here and in the slicer should be consistent, for plot labels and summary statistic values to be consistent. fignum : int Matplotlib figure number to use (default = None, starts new figure). Returns ------- int Matplotlib figure number used to create the plot. """ if not hasattr(slicer, 'nside'): raise ValueError( 'FOPlot to be used with healpix or healpix derived slicers.') fig = plt.figure(fignum) plotDict = {} plotDict.update(self.defaultPlotDict) plotDict.update(userPlotDict) if plotDict['scale'] is None: plotDict['scale'] = (hp.nside2pixarea(slicer.nside, degrees=True) / 1000.0) # Expect metricValue to be something like number of visits cumulativeArea = np.arange( 1, metricValue.compressed().size + 1)[::-1] * plotDict['scale'] plt.plot(np.sort(metricValue.compressed()), cumulativeArea, 'k-', linewidth=plotDict['linewidth'], zorder=0) # This is breaking the rules and calculating the summary stats in two places. # Could just calculate summary stats and pass in labels. rarr = np.array(list(zip(metricValue.compressed())), dtype=[('fO', metricValue.dtype)]) fOArea = metrics.fOArea(col='fO', Asky=plotDict['Asky'], norm=False, nside=slicer.nside).run(rarr) fONv = metrics.fONv(col='fO', Nvisit=plotDict['Nvisits'], norm=False, nside=slicer.nside).run(rarr) plt.axvline(x=plotDict['Nvisits'], linewidth=plotDict['reflinewidth'], color='b') plt.axhline(y=plotDict['Asky'] / 1000., linewidth=plotDict['reflinewidth'], color='r') # Add lines for Nvis_median and fOArea: note if these are -666 (badval), # the default xMin/yMin values will just leave them off the edges of the plot. Nvis_median = fONv['value'][np.where(fONv['name'] == 'MedianNvis')] # Note that Nvis is the number of visits (it's not an area) - so goes on number axis plt.axvline(x=Nvis_median, linewidth=plotDict['reflinewidth'], color='b', alpha=.5, linestyle=':', label=r'f$_0$ Median Nvisits=%.0f' % Nvis_median) plt.axhline(y=fOArea / 1000., linewidth=plotDict['reflinewidth'], color='r', alpha=.5, linestyle=':', label='f$_0$ Area=%.0f' % fOArea) plt.legend(loc='lower left', fontsize='small', numpoints=1) plt.xlabel(plotDict['xlabel']) plt.ylabel(plotDict['ylabel']) plt.title(plotDict['title']) xMin = plotDict['xMin'] xMax = plotDict['xMax'] yMin = plotDict['yMin'] yMax = plotDict['yMax'] if (xMin is not None) or (xMax is not None): plt.xlim([xMin, xMax]) if (yMin is not None) or (yMax is not None): plt.ylim([yMin, yMax]) return fig.number
def scienceRadarBatch(colmap=None, runName='', extraSql=None, extraMetadata=None, nside=64, benchmarkArea=18000, benchmarkNvisits=825, DDF=True): """A batch of metrics for looking at survey performance relative to the SRD and the main science drivers of LSST. Parameters ---------- """ # Hide dependencies from mafContrib.LSSObsStrategy.galaxyCountsMetric_extended import GalaxyCountsMetric_extended from mafContrib import Plasticc_metric, plasticc_slicer, load_plasticc_lc if colmap is None: colmap = ColMapDict('opsimV4') if extraSql is None: extraSql = '' if extraSql == '': joiner = '' else: joiner = ' and ' bundleList = [] healslicer = slicers.HealpixSlicer(nside=nside) subsetPlots = [plots.HealpixSkyMap(), plots.HealpixHistogram()] # Load up the plastic light curves models = ['SNIa-normal', 'KN'] plasticc_models_dict = {} for model in models: plasticc_models_dict[model] = list( load_plasticc_lc(model=model).values()) ######################### # SRD, DM, etc ######################### sql = extraSql displayDict = { 'group': 'SRD', 'subgroup': 'fO', 'order': 0, 'caption': None } metric = metrics.CountMetric(col=colmap['mjd'], metricName='fO') plotDict = { 'xlabel': 'Number of Visits', 'Asky': benchmarkArea, 'Nvisit': benchmarkNvisits, 'xMin': 0, 'xMax': 1500 } summaryMetrics = [ metrics.fOArea(nside=nside, norm=False, metricName='fOArea', Asky=benchmarkArea, Nvisit=benchmarkNvisits), metrics.fOArea(nside=nside, norm=True, metricName='fOArea/benchmark', Asky=benchmarkArea, Nvisit=benchmarkNvisits), metrics.fONv(nside=nside, norm=False, metricName='fONv', Asky=benchmarkArea, Nvisit=benchmarkNvisits), metrics.fONv(nside=nside, norm=True, metricName='fONv/benchmark', Asky=benchmarkArea, Nvisit=benchmarkNvisits) ] caption = 'The FO metric evaluates the overall efficiency of observing. ' caption += ( 'foNv: out of %.2f sq degrees, the area receives at least X and a median of Y visits ' '(out of %d, if compared to benchmark). ' % (benchmarkArea, benchmarkNvisits)) caption += ('fOArea: this many sq deg (out of %.2f sq deg if compared ' 'to benchmark) receives at least %d visits. ' % (benchmarkArea, benchmarkNvisits)) displayDict['caption'] = caption bundle = mb.MetricBundle(metric, healslicer, sql, plotDict=plotDict, displayDict=displayDict, summaryMetrics=summaryMetrics, plotFuncs=[plots.FOPlot()]) bundleList.append(bundle) displayDict['order'] += 1 displayDict = { 'group': 'SRD', 'subgroup': 'Gaps', 'order': 0, 'caption': None } plotDict = {'percentileClip': 95.} for filtername in 'ugrizy': sql = extraSql + joiner + 'filter ="%s"' % filtername metric = metrics.MaxGapMetric() summaryMetrics = [ metrics.PercentileMetric( percentile=95, metricName='95th percentile of Max gap, %s' % filtername) ] bundle = mb.MetricBundle(metric, healslicer, sql, plotFuncs=subsetPlots, summaryMetrics=summaryMetrics, displayDict=displayDict, plotDict=plotDict) bundleList.append(bundle) displayDict['order'] += 1 ######################### # Solar System ######################### # XXX -- may want to do Solar system seperatly # XXX--fraction of NEOs detected (assume some nominal size and albido) # XXX -- fraction of MBAs detected # XXX -- fraction of KBOs detected # XXX--any others? Planet 9s? Comets? Neptune Trojans? ######################### # Cosmology ######################### displayDict = { 'group': 'Cosmology', 'subgroup': 'galaxy counts', 'order': 0, 'caption': None } plotDict = {'percentileClip': 95.} sql = extraSql + joiner + 'filter="i"' metric = GalaxyCountsMetric_extended(filterBand='i', redshiftBin='all', nside=nside) summary = [ metrics.AreaSummaryMetric(area=18000, reduce_func=np.sum, decreasing=True, metricName='N Galaxies (WFD)') ] summary.append(metrics.SumMetric(metricName='N Galaxies (all)')) # make sure slicer has cache off slicer = slicers.HealpixSlicer(nside=nside, useCache=False) bundle = mb.MetricBundle(metric, slicer, sql, plotDict=plotDict, displayDict=displayDict, summaryMetrics=summary, plotFuncs=subsetPlots) bundleList.append(bundle) displayDict['order'] += 1 # let's put Type Ia SN in here displayDict['subgroup'] = 'SNe Ia' metadata = '' # XXX-- use the light curves from PLASTICC here displayDict['Caption'] = 'Fraction of normal SNe Ia' sql = '' slicer = plasticc_slicer(plcs=plasticc_models_dict['SNIa-normal'], seed=42, badval=0) metric = Plasticc_metric(metricName='SNIa') # Set the maskval so that we count missing objects as zero. summary_stats = [metrics.MeanMetric(maskVal=0)] plotFuncs = [plots.HealpixSkyMap()] bundle = mb.MetricBundle(metric, slicer, sql, runName=runName, summaryMetrics=summary_stats, plotFuncs=plotFuncs, metadata=metadata, displayDict=displayDict) bundleList.append(bundle) displayDict['order'] += 1 # XXX--need some sort of metric for weak lensing and camera rotation. ######################### # Variables and Transients ######################### displayDict = { 'group': 'Variables and Transients', 'subgroup': 'Periodic Stars', 'order': 0, 'caption': None } periods = [0.1, 0.5, 1., 2., 5., 10., 20.] # days plotDict = {} metadata = '' sql = extraSql displayDict[ 'Caption'] = 'Measure of how well a periodic signal can be measured combining amplitude and phase coverage. 1 is perfect, 0 is no way to fit' for period in periods: summary = metrics.PercentileMetric( percentile=10., metricName='10th %%-ile Periodic Quality, Period=%.1f days' % period) metric = metrics.PeriodicQualityMetric( period=period, starMag=20., metricName='Periodic Stars, P=%.1f d' % period) bundle = mb.MetricBundle(metric, healslicer, sql, metadata=metadata, displayDict=displayDict, plotDict=plotDict, plotFuncs=subsetPlots, summaryMetrics=summary) bundleList.append(bundle) displayDict['order'] += 1 # XXX add some PLASTICC metrics for kilovnova and tidal disruption events. displayDict['subgroup'] = 'KN' displayDict['caption'] = 'Fraction of Kilonova (from PLASTICC)' sql = '' slicer = plasticc_slicer(plcs=plasticc_models_dict['KN'], seed=43, badval=0) metric = Plasticc_metric(metricName='KN') summary_stats = [metrics.MeanMetric(maskVal=0)] plotFuncs = [plots.HealpixSkyMap()] bundle = mb.MetricBundle(metric, slicer, sql, runName=runName, summaryMetrics=summary_stats, plotFuncs=plotFuncs, metadata=metadata, displayDict=displayDict) bundleList.append(bundle) displayDict['order'] += 1 # XXX -- would be good to add some microlensing events, for both MW and LMC/SMC. ######################### # Milky Way ######################### # Let's do the proper motion, parallax, and DCR degen of a 20nd mag star rmag = 20. displayDict = { 'group': 'Milky Way', 'subgroup': 'Astrometry', 'order': 0, 'caption': None } sql = extraSql metadata = '' plotDict = {'percentileClip': 95.} metric = metrics.ParallaxMetric(metricName='Parallax Error r=%.1f' % (rmag), rmag=rmag, seeingCol=colmap['seeingGeom'], filterCol=colmap['filter'], m5Col=colmap['fiveSigmaDepth'], normalize=False) summary = [ metrics.AreaSummaryMetric(area=18000, reduce_func=np.median, decreasing=False, metricName='Median Parallax Error (WFD)') ] summary.append( metrics.PercentileMetric(percentile=95, metricName='95th Percentile Parallax Error')) bundle = mb.MetricBundle(metric, healslicer, sql, metadata=metadata, displayDict=displayDict, plotDict=plotDict, plotFuncs=subsetPlots, summaryMetrics=summary) bundleList.append(bundle) displayDict['order'] += 1 metric = metrics.ProperMotionMetric( metricName='Proper Motion Error r=%.1f' % rmag, rmag=rmag, m5Col=colmap['fiveSigmaDepth'], mjdCol=colmap['mjd'], filterCol=colmap['filter'], seeingCol=colmap['seeingGeom'], normalize=False) summary = [ metrics.AreaSummaryMetric( area=18000, reduce_func=np.median, decreasing=False, metricName='Median Proper Motion Error (WFD)') ] summary.append( metrics.PercentileMetric( metricName='95th Percentile Proper Motion Error')) bundle = mb.MetricBundle(metric, healslicer, sql, metadata=metadata, displayDict=displayDict, plotDict=plotDict, summaryMetrics=summary, plotFuncs=subsetPlots) bundleList.append(bundle) displayDict['order'] += 1 metric = metrics.ParallaxDcrDegenMetric( metricName='Parallax-DCR degeneracy r=%.1f' % (rmag), rmag=rmag, seeingCol=colmap['seeingEff'], filterCol=colmap['filter'], m5Col=colmap['fiveSigmaDepth']) caption = 'Correlation between parallax offset magnitude and hour angle for a r=%.1f star.' % ( rmag) caption += ' (0 is good, near -1 or 1 is bad).' # XXX--not sure what kind of summary to do here summary = [metrics.MeanMetric(metricName='Mean DCR Degeneracy')] bundle = mb.MetricBundle(metric, healslicer, sql, metadata=metadata, displayDict=displayDict, summaryMetrics=summary, plotFuncs=subsetPlots) bundleList.append(bundle) displayDict['order'] += 1 for b in bundleList: b.setRunName(runName) ######################### # DDF ######################### ddf_time_bundleDicts = [] if DDF: # Hide this import to avoid adding a dependency. from lsst.sims.featureScheduler.surveys import generate_dd_surveys ddf_surveys = generate_dd_surveys() # For doing a high-res sampling of the DDF for co-adds ddf_radius = 1.8 # Degrees ddf_nside = 512 ra, dec = hpid2RaDec(ddf_nside, np.arange(hp.nside2npix(ddf_nside))) displayDict = { 'group': 'DDF depths', 'subgroup': None, 'order': 0, 'caption': None } # Run the inter and intra gaps at the center of the DDFs for survey in ddf_surveys: slicer = slicers.UserPointsSlicer(ra=np.degrees(survey.ra), dec=np.degrees(survey.dec), useCamera=False) ddf_time_bundleDicts.append( interNight(colmap=colmap, slicer=slicer, runName=runName, nside=64, extraSql='note="%s"' % survey.survey_name, subgroup=survey.survey_name)[0]) ddf_time_bundleDicts.append( intraNight(colmap=colmap, slicer=slicer, runName=runName, nside=64, extraSql='note="%s"' % survey.survey_name, subgroup=survey.survey_name)[0]) for survey in ddf_surveys: displayDict['subgroup'] = survey.survey_name # Crop off the u-band only DDF if survey.survey_name[0:4] != 'DD:u': dist_to_ddf = angularSeparation(ra, dec, np.degrees(survey.ra), np.degrees(survey.dec)) goodhp = np.where(dist_to_ddf <= ddf_radius) slicer = slicers.UserPointsSlicer(ra=ra[goodhp], dec=dec[goodhp], useCamera=False) for filtername in ['u', 'g', 'r', 'i', 'z', 'y']: metric = metrics.Coaddm5Metric( metricName=survey.survey_name + ', ' + filtername) summary = [ metrics.MedianMetric(metricName='median depth ' + survey.survey_name + ', ' + filtername) ] sql = extraSql + joiner + 'filter = "%s"' % filtername bundle = mb.MetricBundle(metric, slicer, sql, metadata=metadata, displayDict=displayDict, summaryMetrics=summary, plotFuncs=[]) bundleList.append(bundle) displayDict['order'] += 1 displayDict = { 'group': 'DDF Transients', 'subgroup': None, 'order': 0, 'caption': None } for survey in ddf_surveys: displayDict['subgroup'] = survey.survey_name if survey.survey_name[0:4] != 'DD:u': slicer = plasticc_slicer( plcs=plasticc_models_dict['SNIa-normal'], seed=42, ra_cen=survey.ra, dec_cen=survey.dec, radius=np.radians(3.), useCamera=False) metric = Plasticc_metric(metricName=survey.survey_name + ' SNIa') sql = '' summary_stats = [metrics.MeanMetric(maskVal=0)] plotFuncs = [plots.HealpixSkyMap()] bundle = mb.MetricBundle(metric, slicer, sql, runName=runName, summaryMetrics=summary_stats, plotFuncs=plotFuncs, metadata=metadata, displayDict=displayDict) bundleList.append(bundle) displayDict['order'] += 1 for b in bundleList: b.setRunName(runName) bundleDict = mb.makeBundlesDictFromList(bundleList) intraDict = intraNight(colmap=colmap, runName=runName, nside=nside, extraSql=extraSql, extraMetadata=extraMetadata)[0] interDict = interNight(colmap=colmap, runName=runName, nside=nside, extraSql=extraSql, extraMetadata=extraMetadata)[0] bundleDict.update(intraDict) bundleDict.update(interDict) for ddf_time in ddf_time_bundleDicts: bundleDict.update(ddf_time) return bundleDict
def fOBatch(colmap=None, runName='opsim', extraSql=None, extraMetadata=None, nside=64, benchmarkArea=18000, benchmarkNvisits=825, ditherStacker=None, ditherkwargs=None): """Metrics for calculating fO. Parameters ---------- colmap : dict or None, opt A dictionary with a mapping of column names. Default will use OpsimV4 column names. runName : str, opt The name of the simulated survey. Default is "opsim". nside : int, opt Nside for the healpix slicer. Default 64. extraSql : str or None, opt Additional sql constraint to apply to all metrics. extraMetadata : str or None, opt Additional metadata to apply to all results. ditherStacker: str or lsst.sims.maf.stackers.BaseDitherStacker Optional dither stacker to use to define ra/dec columns. ditherkwargs: dict, opt Optional dictionary of kwargs for the dither stacker. Returns ------- metricBundleDict """ if colmap is None: colmap = ColMapDict('opsimV4') bundleList = [] sql = '' metadata = 'All visits' # Add additional sql constraint (such as wfdWhere) and metadata, if provided. if (extraSql is not None) and (len(extraSql) > 0): sql = extraSql if extraMetadata is None: metadata = extraSql.replace('filter =', '').replace('filter=', '') metadata = metadata.replace('"', '').replace("'", '') if extraMetadata is not None: metadata = extraMetadata subgroup = metadata raCol, decCol, degrees, ditherStacker, ditherMeta = radecCols(ditherStacker, colmap, ditherkwargs) # Don't want dither info in subgroup (too long), but do want it in bundle name. metadata = combineMetadata(metadata, ditherMeta) # Set up fO metric. slicer = slicers.HealpixSlicer(nside=nside, lonCol=raCol, latCol=decCol, latLonDeg=degrees) displayDict = {'group': 'FO metrics', 'subgroup': subgroup, 'order': 0} # Configure the count metric which is what is used for f0 slicer. metric = metrics.CountMetric(col=colmap['mjd'], metricName='fO') plotDict = {'xlabel': 'Number of Visits', 'Asky': benchmarkArea, 'Nvisit': benchmarkNvisits, 'xMin': 0, 'xMax': 1500} summaryMetrics = [metrics.fOArea(nside=nside, norm=False, metricName='fOArea', Asky=benchmarkArea, Nvisit=benchmarkNvisits), metrics.fOArea(nside=nside, norm=True, metricName='fOArea/benchmark', Asky=benchmarkArea, Nvisit=benchmarkNvisits), metrics.fONv(nside=nside, norm=False, metricName='fONv', Asky=benchmarkArea, Nvisit=benchmarkNvisits), metrics.fONv(nside=nside, norm=True, metricName='fONv/benchmark', Asky=benchmarkArea, Nvisit=benchmarkNvisits)] caption = 'The FO metric evaluates the overall efficiency of observing. ' caption += ('foNv: out of %.2f sq degrees, the area receives at least X and a median of Y visits ' '(out of %d, if compared to benchmark). ' % (benchmarkArea, benchmarkNvisits)) caption += ('fOArea: this many sq deg (out of %.2f sq deg if compared ' 'to benchmark) receives at least %d visits. ' % (benchmarkArea, benchmarkNvisits)) displayDict['caption'] = caption bundle = mb.MetricBundle(metric, slicer, sql, plotDict=plotDict, stackerList = [ditherStacker], displayDict=displayDict, summaryMetrics=summaryMetrics, plotFuncs=[plots.FOPlot()], metadata=metadata) bundleList.append(bundle) # Set the runName for all bundles and return the bundleDict. for b in bundleList: b.setRunName(runName) return mb.makeBundlesDictFromList(bundleList)