Ejemplo n.º 1
0
def setupMetrics(opsimName, metadata, plotlabel='', t0=0, tStep=40./24./60./60., years=0,
                 onlyFilterColors=False, verbose=False):
    # Set up metrics and plotDicts (they will be bundled with the appropriate opsim slicers below).
    t = time.time()
    nvisitsMax = 90*(years+1)
    colorMax = int(nvisitsMax/4)
    metricList = []
    plotDictList = []
    figsize = (8, 6)
    if not onlyFilterColors:
        metricList.append(metrics.CountMetric('observationStartMJD', metricName='Nvisits'))
        plotDictList.append({'colorMin': 0, 'colorMax': nvisitsMax,
                             'xlabel': 'Number of visits', 'title': 'Cumulative visits (all bands)',
                             'label': plotlabel, 'metricIsColor': False, 'figsize': figsize})
        for f in (['u', 'g', 'r', 'i', 'z', 'y']):
            metricList.append(metrics.CountSubsetMetric('filter', subset=f, metricName='Nvisits_'+f))
            plotDictList.append({'colorMin': 0, 'colorMax': colorMax, 'cbarFormat': '%d',
                                 'xlabel': 'Number of Visits', 'title': '%s band' %(f),
                                 'label': plotlabel, 'metricIsColor': False, 'figsize': figsize})
    metricList.append(metrics.FilterColorsMetric(t0=t0, tStep=tStep))
    plotDictList.append({'title': 'Simulation %s: %s' %(opsimName, metadata), 'bgcolor': None,
                         'metricIsColor': True, 'figsize': figsize})
    dt, t = dtime(t)
    if verbose:
        print('Set up metrics %f s' %(dt))
    return metricList, plotDictList
Ejemplo n.º 2
0
def nvisitsPerNight(colmap=None,
                    runName='opsim',
                    binNights=1,
                    sqlConstraint=None,
                    metadata=None):
    """Count the number of visits per night through the survey.

    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".
    binNights : int, opt
        Number of nights to count in each bin. Default = 1, count number of visits in each night.
    sqlConstraint : str or None, opt
        Additional constraint to add to any sql constraints (e.g. 'propId=1' or 'fieldID=522').
        Default None, for no additional constraints.
    metadata : str or None, opt
        Additional metadata to add before any below (i.e. "WFD").  Default is None.

    Returns
    -------
    metricBundleDict
    """
    if colmap is None:
        colmap = ColMapDict('opsimV4')

    subgroup = metadata
    if subgroup is None:
        subgroup = 'All visits'

    metadataCaption = metadata
    if metadata is None:
        if sqlConstraint is not None:
            metadataCaption = sqlConstraint
        else:
            metadataCaption = 'all visits'

    bundleList = []

    displayDict = {'group': 'Per Night', 'subgroup': subgroup}
    displayDict['caption'] = 'Number of visits per night for %s.' % (
        metadataCaption)
    displayDict['order'] = 0
    metric = metrics.CountMetric(colmap['mjd'], metricName='Nvisits')
    slicer = slicers.OneDSlicer(sliceColName=colmap['mjd'],
                                binsize=int(binNights))
    bundle = mb.MetricBundle(metric,
                             slicer,
                             sqlConstraint,
                             metadata=metadata,
                             displayDict=displayDict,
                             summaryMetrics=standardSummary())
    bundleList.append(bundle)

    # Set the runName for all bundles and return the bundleDict.
    for b in bundleList:
        b.setRunName(runName)
    return mb.makeBundlesDictFromList(bundleList)
Ejemplo n.º 3
0
def runChips(useCamera=False):
    import numpy as np
    import lsst.sims.maf.slicers as slicers
    import lsst.sims.maf.metrics as metrics
    import lsst.sims.maf.metricBundles as metricBundles
    import lsst.sims.maf.db as db
    from lsst.sims.maf.plots import PlotHandler
    import matplotlib.pylab as plt
    import healpy as hp


    print 'Camera setting = ', useCamera

    database = 'enigma_1189_sqlite.db'
    sqlWhere = 'filter = "r" and night < 800 and fieldRA < %f and fieldDec > %f and fieldDec < 0' % (np.radians(15), np.radians(-15))
    opsdb = db.OpsimDatabase(database)
    outDir = 'Camera'
    resultsDb = db.ResultsDb(outDir=outDir)

    nside=512
    tag = 'F'
    if useCamera:
        tag='T'
    metric = metrics.CountMetric('expMJD', metricName='chipgap_%s'%tag)

    slicer = slicers.HealpixSlicer(nside=nside, useCamera=useCamera)
    bundle1 = metricBundles.MetricBundle(metric,slicer,sqlWhere)

    bg = metricBundles.MetricBundleGroup({0:bundle1},opsdb, outDir=outDir, resultsDb=resultsDb)
    bg.runAll()
    hp.gnomview(bundle1.metricValues, xsize=800,ysize=800, rot=(7,-7,0), unit='Count', min=1)
    plt.savefig(outDir+'/fig'+tag+'.png')
Ejemplo n.º 4
0
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)
Ejemplo n.º 5
0
def setupMetrics(opsimName,
                 metadata,
                 tstart,
                 tnow,
                 plotlabel='',
                 cumulative=False,
                 verbose=False):
    """
    Define and instantiate metrics.
    """
    # Define and set up metrics.
    # Note that it is useful to set up the plotDict so that the min/max range for the plot
    #  is the same for all movie frames.
    t = time.time()
    metricList = []
    plotDictList = []
    #Simple metrics: coadded depth and number of visits
    nvisitsMin = 0
    nvisitsMax = 1000  #300
    coaddMin = 25
    coaddMax = 28
    if not cumulative:
        # Take a guess ... probably will need to be adjusted for your stepsize.
        nvisitsMax = 90  # 15
        coaddMin = 24.0
        coaddMax = 26.5
    figsize = (8, 8)
    title = 'Simulation %s: %s' % (opsimName, metadata)

    metricList.append(
        metrics.Coaddm5Metric('fiveSigmaDepth', metricName='Coaddm5Metric'))
    plotDictList.append({
        'colorMin': coaddMin,
        'colorMax': coaddMax,
        'label': plotlabel,
        'title': title,
        'figsize': figsize
    })

    metricList.append(
        metrics.CountMetric('observationStartMJD', metricName='N_Visits'))
    plotDictList.append({
        'colorMin': nvisitsMin,
        'colorMax': nvisitsMax,
        'cbarFormat': '%d',
        'label': plotlabel,
        'title': title + 'NVisits',
        'figsize': figsize
    })
    dt, t = dtime(t)
    if verbose:
        print('Set up metrics %f s' % (dt))
    return metricList, plotDictList
Ejemplo n.º 6
0
def setupMetrics(args, tstart, tnow, verbose=False):
    """
    Define and instantiate metrics.
    Pass 'args' to access 'cumulative' flag, in order to set better limits for max/min.
    Could potentially access other 'args' values.
    """
    # Define and set up metrics.
    # Note that it is useful to set up the plotDict so that the min/max range for the plot
    #  is the same for all movie frames.
    t = time.time()
    metricList = []
    #Simple metrics: coadded depth and number of visits
    nvisitsMin = 0
    nvisitsMax = 300
    coaddMin = 25
    coaddMax = 28
    if not args.cumulative:
        # Take a guess ... probably will need to be adjusted for your stepsize.
        nvisitsMax = 15
        coaddMin = 24.0
        coaddMax = 26.5
    metricList.append(
        metrics.Coaddm5Metric('fiveSigmaDepth',
                              metricName='Coaddm5Metric',
                              plotDict={
                                  'colorMin': coaddMin,
                                  'colorMax': coaddMax
                              }))
    metricList.append(
        metrics.CountMetric('expMJD',
                            metricName='N_Visits',
                            plotDict={
                                'colorMin': nvisitsMin,
                                'colorMax': nvisitsMax,
                                'cbarFormat': '%d',
                                'title': 'Number of Visits '
                            }))
    # Uniformity wants survey length in years.
    surveyLength = (tnow - tstart) / 365.0
    metricList.append(
        metrics.UniformityMetric('expMJD',
                                 surveyLength=surveyLength,
                                 plotDict={
                                     'colorMin': 0,
                                     'colorMax': 1,
                                     'cbarFormat': '%.2f',
                                     'title': 'Survey Uniformity'
                                 }))
    dt, t = dtime(t)
    if verbose:
        print 'Set up metrics %f s' % (dt)
    return metricList
Ejemplo n.º 7
0
def basicSetup(metricName, colmap=None, nside=64):

    if colmap is None:
        colmap = ColMapDict('opsimV4')

    slicer = slicers.HealpixSlicer(nside=nside,
                                   latCol=colmap['alt'],
                                   lonCol=colmap['az'],
                                   latLonDeg=colmap['raDecDeg'],
                                   useCache=False)
    metric = metrics.CountMetric(colmap['mjd'], metricName=metricName)

    return colmap, slicer, metric
Ejemplo n.º 8
0
def standardSummary():
    """A set of standard summary metrics, to calculate Mean, RMS, Median, #, Max/Min, and # 3-sigma outliers.
    """
    standardSummary = [
        metrics.MeanMetric(),
        metrics.RmsMetric(),
        metrics.MedianMetric(),
        metrics.CountMetric(),
        metrics.MaxMetric(),
        metrics.MinMetric(),
        metrics.NoutliersNsigmaMetric(metricName='N(+3Sigma)', nSigma=3),
        metrics.NoutliersNsigmaMetric(metricName='N(-3Sigma)', nSigma=-3.)
    ]
    return standardSummary
Ejemplo n.º 9
0
def extendedMetrics(colname, replace_colname=None):
    """An extended set of simple metrics for some quantity. Typically applied with unislicer.

    Parameters
    ----------
    colname : str
        The column name to apply the metrics to.
    replace_colname: str or None, opt
        Value to replace colname with in the metricName.
        i.e. if replace_colname='' then metric name is Mean, instead of Mean Airmass, or
        if replace_colname='seeingGeom', then metric name is Mean seeingGeom instead of Mean seeingFwhmGeom.
        Default is None, which does not alter the metric name.

    Returns
    -------
    List of configured metrics.
    """
    extendedMetrics = standardMetrics(colname, replace_colname=None)
    extendedMetrics += [
        metrics.RmsMetric(colname),
        metrics.NoutliersNsigmaMetric(colname,
                                      metricName='N(+3Sigma) ' + colname,
                                      nSigma=3),
        metrics.NoutliersNsigmaMetric(colname,
                                      metricName='N(-3Sigma) ' + colname,
                                      nSigma=-3),
        metrics.PercentileMetric(colname, percentile=25),
        metrics.PercentileMetric(colname, percentile=75),
        metrics.CountMetric(colname)
    ]
    if replace_colname is not None:
        for m in extendedMetrics:
            if len(replace_colname) > 0:
                m.name = m.name.replace('%s' % colname, '%s' % replace_colname)
            else:
                m.name = m.name.rstrip(' %s' % colname)
    return extendedMetrics
Ejemplo n.º 10
0
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)
Ejemplo n.º 11
0
def nvisitsM5Maps(colmap=None,
                  runName='opsim',
                  extraSql=None,
                  extraMetadata=None,
                  nside=64,
                  runLength=10.,
                  ditherStacker=None,
                  ditherkwargs=None):
    """Generate number of visits and Coadded depth per RA/Dec point in all and per filters.

    Parameters
    ----------
    colmap : dict, 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".
    extraSql : str, opt
        Additional constraint to add to any sql constraints (e.g. 'propId=1' or 'fieldID=522').
        Default None, for no additional constraints.
    extraMetadata : str, opt
        Additional metadata to add before any below (i.e. "WFD").  Default is None.
    nside : int, opt
        Nside value for healpix slicer. Default 64.
        If "None" is passed, the healpixslicer-based metrics will be skipped.
    runLength : float, opt
        Length of the simulated survey, for scaling values for the plot limits.
        Default 10.
    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 = []

    subgroup = extraMetadata
    if subgroup is None:
        subgroup = 'All visits'

    raCol, decCol, degrees, ditherStacker, ditherMeta = radecCols(
        ditherStacker, colmap, ditherkwargs)
    extraMetadata = combineMetadata(extraMetadata, ditherMeta)
    # Set up basic all and per filter sql constraints.
    filterlist, colors, orders, sqls, metadata = filterList(
        all=True, extraSql=extraSql, extraMetadata=extraMetadata)
    # Set up some values to make nicer looking plots.
    benchmarkVals = mafUtils.scaleBenchmarks(runLength, benchmark='design')
    # 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
    benchmarkVals['coaddedDepth'] = mafUtils.calcCoaddedDepth(
        benchmarkVals['nvisits'], benchmarkVals['singleVisitDepth'])
    # Scale the nvisit ranges for the runLength.
    nvisitsRange = {
        'u': [20, 80],
        'g': [50, 150],
        'r': [100, 250],
        'i': [100, 250],
        'z': [100, 300],
        'y': [100, 300],
        'all': [700, 1200]
    }
    scale = runLength / 10.0
    for f in nvisitsRange:
        for i in [0, 1]:
            nvisitsRange[f][i] = int(np.floor(nvisitsRange[f][i] * scale))

    # Generate Nvisit maps in all and per filters
    displayDict = {'group': 'Nvisits Maps', 'subgroup': subgroup}
    metric = metrics.CountMetric(colmap['mjd'], metricName='NVisits', units='')
    slicer = slicers.HealpixSlicer(nside=nside,
                                   latCol=decCol,
                                   lonCol=raCol,
                                   latLonDeg=degrees)
    for f in filterlist:
        sql = sqls[f]
        displayDict[
            'caption'] = 'Number of visits per healpix in %s.' % metadata[f]
        displayDict['order'] = orders[f]
        binsize = 2
        if f == 'all':
            binsize = 5
        plotDict = {
            'xMin': nvisitsRange[f][0],
            'xMax': nvisitsRange[f][1],
            'colorMin': nvisitsRange[f][0],
            'colorMax': nvisitsRange[f][1],
            'binsize': binsize,
            'color': colors[f]
        }
        bundle = mb.MetricBundle(metric,
                                 slicer,
                                 sql,
                                 metadata=metadata[f],
                                 stackerList=ditherStacker,
                                 displayDict=displayDict,
                                 plotDict=plotDict,
                                 summaryMetrics=standardSummary())
        bundleList.append(bundle)

    # Generate Coadded depth maps per filter
    displayDict = {'group': 'Coadded M5 Maps', 'subgroup': subgroup}
    metric = metrics.Coaddm5Metric(m5Col=colmap['fiveSigmaDepth'],
                                   metricName='CoaddM5')
    slicer = slicers.HealpixSlicer(nside=nside,
                                   latCol=decCol,
                                   lonCol=raCol,
                                   latLonDeg=degrees)
    for f in filterlist:
        # Skip "all" for coadded depth.
        if f == 'all':
            continue
        mag_zp = benchmarkVals['coaddedDepth'][f]
        sql = sqls[f]
        displayDict['caption'] = 'Coadded depth per healpix, with %s benchmark value subtracted (%.1f) ' \
                                 'in %s.' % (f, mag_zp, metadata[f])
        displayDict[
            'caption'] += ' More positive numbers indicate fainter limiting magnitudes.'
        displayDict['order'] = orders[f]
        plotDict = {
            'zp': mag_zp,
            'xMin': -0.6,
            'xMax': 0.6,
            'xlabel': 'coadded m5 - %.1f' % mag_zp,
            'colorMin': -0.6,
            'colorMax': 0.6,
            'color': colors[f]
        }
        bundle = mb.MetricBundle(metric,
                                 slicer,
                                 sql,
                                 metadata=metadata[f],
                                 stackerList=ditherStacker,
                                 displayDict=displayDict,
                                 plotDict=plotDict,
                                 summaryMetrics=standardSummary())
        bundleList.append(bundle)

    # Set the runName for all bundles and return the bundleDict.
    for b in bundleList:
        b.setRunName(runName)
    return mb.makeBundlesDictFromList(bundleList)
Ejemplo n.º 12
0
def metadataBasicsAngle(value,
                        colmap=None,
                        runName='opsim',
                        valueName=None,
                        groupName=None,
                        extraSql=None,
                        extraMetadata=None,
                        nside=64,
                        ditherStacker=None,
                        ditherkwargs=None):
    """Calculate basic metrics on visit metadata 'value', where value is a wrap-around angle.

    Calculates extended standard metrics (with unislicer) on the quantity (all visits and per filter),
    makes histogram of the value (all visits and per filter),


    Parameters
    ----------
    value : str
        The column name for the quantity to evaluate. (column name in the database or created by a stacker).
    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".
    valueName : str, opt
        The name of the value to be reported in the resultsDb and added to the metric.
        This is intended to help standardize metric comparison between sim versions.
        value = name as it is in the database (seeingFwhmGeom, etc).
        valueName = name to be recorded ('seeingGeom', etc.).  Default is None, which will match 'value'.
    groupName : str, opt
        The group name for this quantity in the displayDict. Default is the same as 'valueName', capitalized.
    extraSql : str, opt
        Additional constraint to add to any sql constraints (e.g. 'propId=1' or 'fieldID=522').
        Default None, for no additional constraints.
    extraMetadata : str, opt
        Additional metadata to add before any below (i.e. "WFD").  Default is None.
    nside : int, opt
        Nside value for healpix slicer. Default 64.
        If "None" is passed, the healpixslicer-based metrics will be skipped.
    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 = []

    if valueName is None:
        valueName = value

    if groupName is None:
        groupName = valueName.capitalize()
        subgroup = extraMetadata
    else:
        groupName = groupName.capitalize()
        subgroup = valueName.capitalize()

    if subgroup is None:
        subgroup = 'All visits'

    displayDict = {'group': groupName, 'subgroup': subgroup}

    raCol, decCol, degrees, ditherStacker, ditherMeta = radecCols(
        ditherStacker, colmap, ditherkwargs)
    extraMetadata = combineMetadata(extraMetadata, ditherMeta)
    # Set up basic all and per filter sql constraints.
    filterlist, colors, orders, sqls, metadata = filterList(
        all=True, extraSql=extraSql, extraMetadata=extraMetadata)

    stackerList = [ditherStacker]

    # Summarize values over all and per filter.
    slicer = slicers.UniSlicer()
    for f in filterlist:
        for m in standardAngleMetrics(value, replace_colname=valueName):
            displayDict['caption'] = '%s for %s.' % (m.name, metadata[f])
            displayDict['order'] = orders[f]
            bundle = mb.MetricBundle(m,
                                     slicer,
                                     sqls[f],
                                     stackerList=stackerList,
                                     metadata=metadata[f],
                                     displayDict=displayDict)
            bundleList.append(bundle)

    # Histogram values over all and per filter.
    for f in filterlist:
        displayDict['caption'] = 'Histogram of %s' % (value)
        if valueName != value:
            displayDict['caption'] += ' (%s)' % (valueName)
        displayDict['caption'] += ' for %s.' % (metadata[f])
        displayDict['order'] = orders[f]
        m = metrics.CountMetric(value, metricName='%s Histogram' % (valueName))
        slicer = slicers.OneDSlicer(sliceColName=value)
        bundle = mb.MetricBundle(m,
                                 slicer,
                                 sqls[f],
                                 stackerList=stackerList,
                                 metadata=metadata[f],
                                 displayDict=displayDict)
        bundleList.append(bundle)

    # Make maps of min/median/max for all and per filter, per RA/Dec, with standard summary stats.
    mList = []
    mList.append(
        metrics.MeanAngleMetric(value,
                                metricName='AngleMean %s' % (valueName)))
    mList.append(
        metrics.FullRangeAngleMetric(value,
                                     metricName='AngleRange %s' % (valueName)))
    mList.append(
        metrics.RmsAngleMetric(value, metricName='AngleRms %s' % (valueName)))
    slicer = slicers.HealpixSlicer(nside=nside,
                                   latCol=decCol,
                                   lonCol=raCol,
                                   latLonDeg=degrees)
    subsetPlots = [plots.HealpixSkyMap(), plots.HealpixHistogram()]
    for f in filterlist:
        for m in mList:
            displayDict['caption'] = 'Map of %s' % m.name
            if valueName != value:
                displayDict['caption'] += ' (%s)' % value
            displayDict['caption'] += ' for %s.' % metadata[f]
            displayDict['order'] = orders[f]
            bundle = mb.MetricBundle(m,
                                     slicer,
                                     sqls[f],
                                     stackerList=stackerList,
                                     metadata=metadata[f],
                                     plotFuncs=subsetPlots,
                                     displayDict=displayDict,
                                     summaryMetrics=standardSummary())
            bundleList.append(bundle)

    # Set the runName for all bundles and return the bundleDict.
    for b in bundleList:
        b.setRunName(runName)
    return mb.makeBundlesDictFromList(bundleList)
Ejemplo n.º 13
0
def metadataBasics(value,
                   colmap=None,
                   runName='opsim',
                   valueName=None,
                   groupName=None,
                   extraSql=None,
                   extraMetadata=None,
                   nside=64,
                   filterlist=('u', 'g', 'r', 'i', 'z', 'y')):
    """Calculate basic metrics on visit metadata 'value' (e.g. airmass, normalized airmass, seeing..).

    Calculates extended standard metrics (with unislicer) on the quantity (all visits and per filter),
    makes histogram of the value (all visits and per filter),


    Parameters
    ----------
    value : str
        The column name for the quantity to evaluate. (column name in the database or created by a stacker).
    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".
    valueName : str, opt
        The name of the value to be reported in the resultsDb and added to the metric.
        This is intended to help standardize metric comparison between sim versions.
        value = name as it is in the database (seeingFwhmGeom, etc).
        valueName = name to be recorded ('seeingGeom', etc.).  Default is None, which is set to match value.
    groupName : str, opt
        The group name for this quantity in the displayDict. Default is the same as 'value', capitalized.
    extraSql : str, opt
        Additional constraint to add to any sql constraints (e.g. 'propId=1' or 'fieldID=522').
        Default None, for no additional constraints.
    extraMetadata : str, opt
        Additional metadata to add before any below (i.e. "WFD").  Default is None.
    nside : int, opt
        Nside value for healpix slicer. Default 64.
        If "None" is passed, the healpixslicer-based metrics will be skipped.
    filterlist : list of str, opt
        List of the filternames to use for "per filter" evaluation. Default ('u', 'g', 'r', 'i', 'z', 'y').
        If None is passed, the per-filter evaluations will be skipped.

    Returns
    -------
    metricBundleDict
    """
    if colmap is None:
        colmap = ColMapDict('opsimV4')
    bundleList = []

    if valueName is None:
        valueName = value

    if groupName is None:
        groupName = valueName.capitalize()
        subgroup = extraMetadata
    else:
        groupName = groupName.capitalize()
        subgroup = valueName.capitalize()

    displayDict = {'group': groupName, 'subgroup': subgroup}

    sqlconstraints = ['']
    metadata = ['all bands']
    if filterlist is not None:
        sqlconstraints += [
            '%s = "%s"' % (colmap['filter'], f) for f in filterlist
        ]
        metadata += ['%s band' % f for f in filterlist]
    if (extraSql is not None) and (len(extraSql) > 0):
        tmp = []
        for s in sqlconstraints:
            if len(s) == 0:
                tmp.append(extraSql)
            else:
                tmp.append('%s and (%s)' % (s, extraSql))
        sqlconstraints = tmp
        if extraMetadata is None:
            metadata = ['%s %s' % (extraSql, m) for m in metadata]
    if extraMetadata is not None:
        metadata = ['%s %s' % (extraMetadata, m) for m in metadata]

    # Summarize values over all and per filter (min/mean/median/max/percentiles/outliers/rms).
    slicer = slicers.UniSlicer()
    displayDict['caption'] = None
    for sql, meta in zip(sqlconstraints, metadata):
        displayDict['order'] = -1
        for m in extendedMetrics(value, replace_colname=valueName):
            displayDict['order'] += 1
            bundle = mb.MetricBundle(m,
                                     slicer,
                                     sql,
                                     metadata=meta,
                                     displayDict=displayDict)
            bundleList.append(bundle)

    # Histogram values over all and per filter.
    for sql, meta in zip(sqlconstraints, metadata):
        displayDict['caption'] = 'Histogram of %s' % (value)
        if valueName != value:
            displayDict['caption'] += ' (%s)' % (valueName)
        displayDict['caption'] += ' for %s visits.' % (meta)
        displayDict['order'] += 1
        m = metrics.CountMetric(value, metricName='%s Histogram' % (valueName))
        slicer = slicers.OneDSlicer(sliceColName=value)
        bundle = mb.MetricBundle(m,
                                 slicer,
                                 sql,
                                 metadata=meta,
                                 displayDict=displayDict)
        bundleList.append(bundle)

    # Make maps of min/median/max for all and per filter, per RA/Dec, with standard summary stats.
    mList = []
    mList.append(metrics.MinMetric(value, metricName='Min %s' % (valueName)))
    mList.append(
        metrics.MedianMetric(value, metricName='Median %s' % (valueName)))
    mList.append(metrics.MaxMetric(value, metricName='Max %s' % (valueName)))
    slicer = slicers.HealpixSlicer(nside=nside,
                                   latCol=colmap['dec'],
                                   lonCol=colmap['ra'],
                                   latLonDeg=colmap['raDecDeg'])
    subsetPlots = [plots.HealpixSkyMap(), plots.HealpixHistogram()]
    displayDict['caption'] = None
    displayDict['order'] = -1
    for sql, meta in zip(sqlconstraints, metadata):
        for m in mList:
            displayDict['order'] += 1
            bundle = mb.MetricBundle(m,
                                     slicer,
                                     sql,
                                     metadata=meta,
                                     plotFuncs=subsetPlots,
                                     displayDict=displayDict,
                                     summaryMetrics=standardSummary())
            bundleList.append(bundle)

    # Set the runName for all bundles and return the bundleDict.
    for b in bundleList:
        b.setRunName(runName)
    return mb.makeBundlesDictFromList(bundleList)
Ejemplo n.º 14
0
def glanceBatch(colmap=None,
                runName='opsim',
                nside=64,
                filternames=('u', 'g', 'r', 'i', 'z', 'y'),
                nyears=10,
                pairnside=32,
                sqlConstraint=None):
    """Generate a handy set of metrics that give a quick overview of how well a survey performed.
    This is a meta-set of other batches, to some extent.

    Parameters
    ----------
    colmap : dict, opt
        A dictionary with a mapping of column names. Default will use OpsimV4 column names.
    run_name : str, opt
        The name of the simulated survey. Default is "opsim".
    nside : int, opt
        The nside for the healpix slicers. Default 64.
    filternames : list of str, opt
        The list of individual filters to use when running metrics.
        Default is ('u', 'g', 'r', 'i', 'z', 'y').
        There is always an all-visits version of the metrics run as well.
    nyears : int (10)
        How many years to attempt to make hourglass plots for
    pairnside : int (32)
        nside to use for the pair fraction metric (it's slow, so nice to use lower resolution)
    sqlConstraint : str or None, opt
        Additional SQL constraint to apply to all metrics.

    Returns
    -------
    metricBundleDict
    """
    if isinstance(colmap, str):
        raise ValueError('colmap must be a dictionary, not a string')

    if colmap is None:
        colmap = ColMapDict('opsimV4')

    bundleList = []

    if sqlConstraint is None:
        sqlC = ''
    else:
        sqlC = '(%s) and' % sqlConstraint

    sql_per_filt = [
        '%s %s="%s"' % (sqlC, colmap['filter'], filtername)
        for filtername in filternames
    ]
    sql_per_and_all_filters = [sqlConstraint] + sql_per_filt

    standardStats = standardSummary()
    subsetPlots = [plots.HealpixSkyMap(), plots.HealpixHistogram()]

    # Super basic things
    displayDict = {'group': 'Basic Stats', 'order': 1}
    sql = sqlConstraint
    slicer = slicers.UniSlicer()
    # Length of Survey
    metric = metrics.FullRangeMetric(col=colmap['mjd'],
                                     metricName='Length of Survey (days)')
    bundle = metricBundles.MetricBundle(metric,
                                        slicer,
                                        sql,
                                        displayDict=displayDict)
    bundleList.append(bundle)

    # Total number of filter changes
    metric = metrics.NChangesMetric(col=colmap['filter'],
                                    orderBy=colmap['mjd'])
    bundle = metricBundles.MetricBundle(metric,
                                        slicer,
                                        sql,
                                        displayDict=displayDict)
    bundleList.append(bundle)

    # Total open shutter fraction
    metric = metrics.OpenShutterFractionMetric(
        slewTimeCol=colmap['slewtime'],
        expTimeCol=colmap['exptime'],
        visitTimeCol=colmap['visittime'])
    bundle = metricBundles.MetricBundle(metric,
                                        slicer,
                                        sql,
                                        displayDict=displayDict)
    bundleList.append(bundle)

    # Total effective exposure time
    metric = metrics.TeffMetric(m5Col=colmap['fiveSigmaDepth'],
                                filterCol=colmap['filter'],
                                normed=True)
    for sql in sql_per_and_all_filters:
        bundle = metricBundles.MetricBundle(metric,
                                            slicer,
                                            sql,
                                            displayDict=displayDict)
        bundleList.append(bundle)

    # Number of observations, all and each filter
    metric = metrics.CountMetric(col=colmap['mjd'],
                                 metricName='Number of Exposures')
    for sql in sql_per_and_all_filters:
        bundle = metricBundles.MetricBundle(metric,
                                            slicer,
                                            sql,
                                            displayDict=displayDict)
        bundleList.append(bundle)

    # The alt/az plots of all the pointings
    slicer = slicers.HealpixSlicer(nside=nside,
                                   latCol='zenithDistance',
                                   lonCol=colmap['az'],
                                   latLonDeg=colmap['raDecDeg'],
                                   useCache=False)
    stacker = stackers.ZenithDistStacker(altCol=colmap['alt'],
                                         degrees=colmap['raDecDeg'])
    metric = metrics.CountMetric(colmap['mjd'],
                                 metricName='Nvisits as function of Alt/Az')
    plotFuncs = [plots.LambertSkyMap()]
    for sql in sql_per_and_all_filters:
        bundle = metricBundles.MetricBundle(metric,
                                            slicer,
                                            sql,
                                            plotFuncs=plotFuncs,
                                            displayDict=displayDict,
                                            stackerList=[stacker])
        bundleList.append(bundle)

    # Things to check per night
    # Open Shutter per night
    displayDict = {'group': 'Pointing Efficency', 'order': 2}
    slicer = slicers.OneDSlicer(sliceColName=colmap['night'], binsize=1)
    metric = metrics.OpenShutterFractionMetric(
        slewTimeCol=colmap['slewtime'],
        expTimeCol=colmap['exptime'],
        visitTimeCol=colmap['visittime'])
    sql = sqlConstraint
    bundle = metricBundles.MetricBundle(metric,
                                        slicer,
                                        sql,
                                        summaryMetrics=standardStats,
                                        displayDict=displayDict)
    bundleList.append(bundle)

    # Number of filter changes per night
    slicer = slicers.OneDSlicer(sliceColName=colmap['night'], binsize=1)
    metric = metrics.NChangesMetric(col=colmap['filter'],
                                    orderBy=colmap['mjd'],
                                    metricName='Filter Changes')
    bundle = metricBundles.MetricBundle(metric,
                                        slicer,
                                        sql,
                                        summaryMetrics=standardStats,
                                        displayDict=displayDict)
    bundleList.append(bundle)

    # A few basic maps
    # Number of observations, coadded depths
    displayDict = {'group': 'Basic Maps', 'order': 3}
    slicer = slicers.HealpixSlicer(nside=nside,
                                   latCol=colmap['dec'],
                                   lonCol=colmap['ra'],
                                   latLonDeg=colmap['raDecDeg'])
    metric = metrics.CountMetric(col=colmap['mjd'])
    plotDict = {'percentileClip': 95.}
    for sql in sql_per_and_all_filters:
        bundle = metricBundles.MetricBundle(metric,
                                            slicer,
                                            sql,
                                            summaryMetrics=standardStats,
                                            displayDict=displayDict,
                                            plotDict=plotDict)
        bundleList.append(bundle)

    metric = metrics.Coaddm5Metric(m5Col=colmap['fiveSigmaDepth'])
    for sql in sql_per_and_all_filters:
        bundle = metricBundles.MetricBundle(metric,
                                            slicer,
                                            sql,
                                            summaryMetrics=standardStats,
                                            displayDict=displayDict)
        bundleList.append(bundle)

    # Checking a few basic science things
    # Maybe check astrometry, observation pairs, SN
    plotDict = {'percentileClip': 95.}
    displayDict = {'group': 'Science', 'subgroup': 'Astrometry', 'order': 4}

    stackerList = []
    stacker = stackers.ParallaxFactorStacker(raCol=colmap['ra'],
                                             decCol=colmap['dec'],
                                             degrees=colmap['raDecDeg'],
                                             dateCol=colmap['mjd'])
    stackerList.append(stacker)

    # Maybe parallax and proper motion, fraction of visits in a good pair for SS
    displayDict['caption'] = r'Parallax precision of an $r=20$ flat SED star'
    metric = metrics.ParallaxMetric(m5Col=colmap['fiveSigmaDepth'],
                                    filterCol=colmap['filter'],
                                    seeingCol=colmap['seeingGeom'])
    sql = sqlConstraint
    bundle = metricBundles.MetricBundle(metric,
                                        slicer,
                                        sql,
                                        plotFuncs=subsetPlots,
                                        displayDict=displayDict,
                                        stackerList=stackerList,
                                        plotDict=plotDict)
    bundleList.append(bundle)
    displayDict[
        'caption'] = r'Proper motion precision of an $r=20$ flat SED star'
    metric = metrics.ProperMotionMetric(m5Col=colmap['fiveSigmaDepth'],
                                        mjdCol=colmap['mjd'],
                                        filterCol=colmap['filter'],
                                        seeingCol=colmap['seeingGeom'])
    bundle = metricBundles.MetricBundle(metric,
                                        slicer,
                                        sql,
                                        plotFuncs=subsetPlots,
                                        displayDict=displayDict,
                                        plotDict=plotDict)
    bundleList.append(bundle)

    # Solar system stuff
    displayDict['caption'] = 'Fraction of observations that are in pairs'
    displayDict['subgroup'] = 'Solar System'

    sql = '%s (filter="g" or filter="r" or filter="i")' % sqlC
    pairSlicer = slicers.HealpixSlicer(nside=pairnside,
                                       latCol=colmap['dec'],
                                       lonCol=colmap['ra'],
                                       latLonDeg=colmap['raDecDeg'])
    metric = metrics.PairFractionMetric(mjdCol=colmap['mjd'])
    bundle = metricBundles.MetricBundle(metric,
                                        pairSlicer,
                                        sql,
                                        plotFuncs=subsetPlots,
                                        displayDict=displayDict)
    bundleList.append(bundle)

    # stats from the note column
    if 'note' in colmap.keys():
        displayDict = {'group': 'Basic Stats', 'subgroup': 'Percent stats'}
        metric = metrics.StringCountMetric(col=colmap['note'],
                                           percent=True,
                                           metricName='Percents')
        sql = ''
        slicer = slicers.UniSlicer()
        bundle = metricBundles.MetricBundle(metric,
                                            slicer,
                                            sql,
                                            displayDict=displayDict)
        bundleList.append(bundle)
        displayDict['subgroup'] = 'Count Stats'
        metric = metrics.StringCountMetric(col=colmap['note'],
                                           metricName='Counts')
        bundle = metricBundles.MetricBundle(metric,
                                            slicer,
                                            sql,
                                            displayDict=displayDict)
        bundleList.append(bundle)

    for b in bundleList:
        b.setRunName(runName)

    # Add hourglass plots.
    hrDict = hourglassBatch(colmap=colmap,
                            runName=runName,
                            nyears=nyears,
                            extraSql=sqlConstraint)

    # Add basic slew stats.
    try:
        slewDict = slewBasics(colmap=colmap, runName=runName)
    except KeyError as e:
        warnings.warn(
            'Could not add slew stats: missing required key %s from colmap' %
            (e))

    bd = metricBundles.makeBundlesDictFromList(bundleList)
    bd.update(slewDict)
    bd.update(hrDict)
    return bd
Ejemplo n.º 15
0
def metadataBasics(value,
                   colmap=None,
                   runName='opsim',
                   valueName=None,
                   groupName=None,
                   extraSql=None,
                   extraMetadata=None,
                   nside=64):
    """Calculate basic metrics on visit metadata 'value' (e.g. airmass, normalized airmass, seeing..).
    Calculates this around the sky (HealpixSlicer), makes histograms of all visits (OneDSlicer),
    and calculates statistics on all visits (UniSlicer) for the quantity in all visits and per filter.

    TODO: handle stackers which need configuration (degrees, in particular) more automatically.
    Currently have a hack for HA & normairmass.

    Parameters
    ----------
    value : str
        The column name for the quantity to evaluate. (column name in the database or created by a stacker).
    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".
    valueName : str, opt
        The name of the value to be reported in the resultsDb and added to the metric.
        This is intended to help standardize metric comparison between sim versions.
        value = name as it is in the database (seeingFwhmGeom, etc).
        valueName = name to be recorded ('seeingGeom', etc.).  Default is None, which will match 'value'.
    groupName : str, opt
        The group name for this quantity in the displayDict. Default is the same as 'valueName', capitalized.
    extraSql : str, opt
        Additional constraint to add to any sql constraints (e.g. 'propId=1' or 'fieldID=522').
        Default None, for no additional constraints.
    extraMetadata : str, opt
        Additional metadata to add before any below (i.e. "WFD").  Default is None.
    nside : int, opt
        Nside value for healpix slicer. Default 64.
        If "None" is passed, the healpixslicer-based metrics will be skipped.

    Returns
    -------
    metricBundleDict
    """
    if colmap is None:
        colmap = ColMapDict('fbs')
    bundleList = []

    if valueName is None:
        valueName = value

    if groupName is None:
        groupName = valueName.capitalize()
        subgroup = extraMetadata
    else:
        groupName = groupName.capitalize()
        subgroup = valueName.capitalize()

    if subgroup is None:
        subgroup = 'All visits'

    displayDict = {'group': groupName, 'subgroup': subgroup}

    raCol, decCol, degrees, ditherStacker, ditherMeta = radecCols(
        None, colmap, None)
    extraMetadata = combineMetadata(extraMetadata, ditherMeta)
    # Set up basic all and per filter sql constraints.
    filterlist, colors, orders, sqls, metadata = filterList(
        all=True, extraSql=extraSql, extraMetadata=extraMetadata)

    # Hack to make HA work, but really I need to account for any stackers/colmaps.
    if value == 'HA':
        stackerList = [
            stackers.HourAngleStacker(lstCol=colmap['lst'],
                                      raCol=raCol,
                                      degrees=degrees)
        ]
    elif value == 'normairmass':
        stackerList = [stackers.NormAirmassStacker(degrees=degrees)]
    else:
        stackerList = None

    # Summarize values over all and per filter (min/mean/median/max/percentiles/outliers/rms).
    slicer = slicers.UniSlicer()
    for f in filterlist:
        for m in extendedMetrics(value, replace_colname=valueName):
            displayDict['caption'] = '%s for %s.' % (m.name, metadata[f])
            displayDict['order'] = orders[f]
            bundle = mb.MetricBundle(m,
                                     slicer,
                                     sqls[f],
                                     stackerList=stackerList,
                                     metadata=metadata[f],
                                     displayDict=displayDict)
            bundleList.append(bundle)

    # Histogram values over all and per filter.
    for f in filterlist:
        displayDict['caption'] = 'Histogram of %s' % (value)
        if valueName != value:
            displayDict['caption'] += ' (%s)' % (valueName)
        displayDict['caption'] += ' for %s.' % (metadata[f])
        displayDict['order'] = orders[f]
        m = metrics.CountMetric(value, metricName='%s Histogram' % (valueName))
        slicer = slicers.OneDSlicer(sliceColName=value)
        bundle = mb.MetricBundle(m,
                                 slicer,
                                 sqls[f],
                                 stackerList=stackerList,
                                 metadata=metadata[f],
                                 displayDict=displayDict)
        bundleList.append(bundle)

    # Make maps of min/median/max for all and per filter, per RA/Dec, with standard summary stats.
    mList = []
    mList.append(metrics.MinMetric(value, metricName='Min %s' % (valueName)))
    mList.append(
        metrics.MedianMetric(value, metricName='Median %s' % (valueName)))
    mList.append(metrics.MaxMetric(value, metricName='Max %s' % (valueName)))
    slicer = slicers.HealpixSlicer(nside=nside,
                                   latCol=decCol,
                                   lonCol=raCol,
                                   latLonDeg=degrees)
    subsetPlots = [plots.HealpixSkyMap(), plots.HealpixHistogram()]
    for f in filterlist:
        for m in mList:
            displayDict['caption'] = 'Map of %s' % m.name
            if valueName != value:
                displayDict['caption'] += ' (%s)' % value
            displayDict['caption'] += ' for %s.' % metadata[f]
            displayDict['order'] = orders[f]
            bundle = mb.MetricBundle(m,
                                     slicer,
                                     sqls[f],
                                     stackerList=stackerList,
                                     metadata=metadata[f],
                                     plotFuncs=subsetPlots,
                                     displayDict=displayDict,
                                     summaryMetrics=standardSummary())
            bundleList.append(bundle)

    # Set the runName for all bundles and return the bundleDict.
    for b in bundleList:
        b.setRunName(runName)
    return mb.makeBundlesDictFromList(bundleList)
Ejemplo n.º 16
0
def nvisitsM5Maps(colmap=None,
                  runName='opsim',
                  extraSql=None,
                  extraMetadata=None,
                  nside=64,
                  filterlist=('u', 'g', 'r', 'i', 'z', 'y')):
    """Generate number of visits and Coadded depth per RA/Dec point in all and per filters.

    Parameters
    ----------
    colmap : dict, 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".
    extraSql : str, opt
        Additional constraint to add to any sql constraints (e.g. 'propId=1' or 'fieldID=522').
        Default None, for no additional constraints.
    extraMetadata : str, opt
        Additional metadata to add before any below (i.e. "WFD").  Default is None.
    nside : int, opt
        Nside value for healpix slicer. Default 64.
        If "None" is passed, the healpixslicer-based metrics will be skipped.
    filterlist : list of str, opt
        List of the filternames to use for "per filter" evaluation. Default ('u', 'g', 'r', 'i', 'z', 'y').
        If None is passed, the per-filter evaluations will be skipped.

    Returns
    -------
    metricBundleDict
    """
    if colmap is None:
        colmap = ColMapDict('opsimV4')
    bundleList = []

    subgroup = extraMetadata
    if subgroup is None:
        subgroup = 'All visits'

    # Set up basic all and per filter sql constraints.
    sqlconstraints = ['']
    metadata = ['all bands']
    if filterlist is not None:
        sqlconstraints += [
            '%s = "%s"' % (colmap['filter'], f) for f in filterlist
        ]
    metadata += ['%s band' % f for f in filterlist]

    # Add additional sql constraint (such as wfdWhere) and metadata, if provided.
    if (extraSql is not None) and (len(extraSql) > 0):
        tmp = []
        for s in sqlconstraints:
            if len(s) == 0:
                tmp.append(extraSql)
            else:
                tmp.append('%s and (%s)' % (s, extraSql))
        sqlconstraints = tmp
        if extraMetadata is None:
            metadata = ['%s %s' % (extraSql, m) for m in metadata]
    if extraMetadata is not None:
        metadata = ['%s %s' % (extraMetadata, m) for m in metadata]
    metadataCaption = extraMetadata
    if metadataCaption is None:
        metadataCaption = 'all visits'

    # Generate Nvisit maps in all and per filters
    displayDict = {'group': 'Nvisits', 'subgroup': subgroup}
    metric = metrics.CountMetric(colmap['mjd'], metricName='NVisits')
    slicer = slicers.HealpixSlicer(nside=nside,
                                   latCol=colmap['dec'],
                                   lonCol=colmap['ra'],
                                   latLonDeg=colmap['raDecDeg'])
    displayDict['order'] = -1
    for sql, meta in zip(sqlconstraints, metadata):
        displayDict['caption'] = 'Number of visits per healpix in %s band(s), ' \
                                 'for %s visits.' % (meta.lstrip('%s ' % extraMetadata), metadataCaption)
        displayDict['order'] += 1
        bundle = mb.MetricBundle(metric,
                                 slicer,
                                 sql,
                                 metadata=meta,
                                 displayDict=displayDict,
                                 summaryMetrics=standardSummary())
        bundleList.append(bundle)

    # Generate Coadded depth maps in all and per filters
    displayDict = {'group': 'Coadded m5', 'subgroup': subgroup}
    metric = metrics.Coaddm5Metric(m5Col=colmap['fiveSigmaDepth'],
                                   metricName='CoaddM5')
    slicer = slicers.HealpixSlicer(nside=nside,
                                   latCol=colmap['dec'],
                                   lonCol=colmap['ra'],
                                   latLonDeg=colmap['raDecDeg'])
    displayDict['order'] = -1
    for sql, meta in zip(sqlconstraints, metadata):
        displayDict['caption'] = 'Number of visits per healpix in %s band(s), ' \
                                 'for %s visits.' % (meta.lstrip('%s ' % extraMetadata), metadataCaption)
        displayDict['order'] += 1
        bundle = mb.MetricBundle(metric,
                                 slicer,
                                 sql,
                                 metadata=meta,
                                 displayDict=displayDict,
                                 summaryMetrics=standardSummary())
        bundleList.append(bundle)

    # Set the runName for all bundles and return the bundleDict.
    for b in bundleList:
        b.setRunName(runName)
    return mb.makeBundlesDictFromList(bundleList)
Ejemplo n.º 17
0
def makeBundleList(dbFile,
                   night=1,
                   nside=64,
                   latCol='fieldDec',
                   lonCol='fieldRA',
                   notes=True,
                   colmap=None):
    """
    Make a bundleList of things to run
    """

    if colmap is None:
        colmap = ColMapDict('opsimV4')

    mjdCol = 'observationStartMJD'
    altCol = 'altitude'
    azCol = 'azimuth'
    # Construct sql queries for each filter and all filters
    filters = ['u', 'g', 'r', 'i', 'z', 'y']
    sqls = ['night=%i and filter="%s"' % (night, f) for f in filters]
    sqls.append('night=%i' % night)

    bundleList = []
    plotFuncs_lam = [plots.LambertSkyMap()]

    # Hourglass
    hourslicer = slicers.HourglassSlicer()
    displayDict = {'group': 'Hourglass'}
    md = ''
    sql = 'night=%i' % night
    metric = metrics.HourglassMetric(nightCol=colmap['night'],
                                     mjdCol=colmap['mjd'],
                                     metricName='Hourglass')
    bundle = metricBundles.MetricBundle(metric,
                                        hourslicer,
                                        constraint=sql,
                                        metadata=md,
                                        displayDict=displayDict)
    bundleList.append(bundle)

    reg_slicer = slicers.HealpixSlicer(nside=nside,
                                       lonCol=lonCol,
                                       latCol=latCol,
                                       latLonDeg=True)
    altaz_slicer = slicers.HealpixSlicer(nside=nside,
                                         latCol=altCol,
                                         latLonDeg=True,
                                         lonCol=azCol,
                                         useCache=False)

    unislicer = slicers.UniSlicer()
    for sql in sqls:

        # Number of exposures
        metric = metrics.CountMetric(mjdCol, metricName='N visits')
        bundle = metricBundles.MetricBundle(metric, reg_slicer, sql)
        bundleList.append(bundle)
        metric = metrics.CountMetric(mjdCol, metricName='N visits alt az')
        bundle = metricBundles.MetricBundle(metric,
                                            altaz_slicer,
                                            sql,
                                            plotFuncs=plotFuncs_lam)
        bundleList.append(bundle)

        metric = metrics.MeanMetric(mjdCol, metricName='Mean Visit Time')
        bundle = metricBundles.MetricBundle(metric, reg_slicer, sql)
        bundleList.append(bundle)
        metric = metrics.MeanMetric(mjdCol,
                                    metricName='Mean Visit Time alt az')
        bundle = metricBundles.MetricBundle(metric,
                                            altaz_slicer,
                                            sql,
                                            plotFuncs=plotFuncs_lam)
        bundleList.append(bundle)

        metric = metrics.CountMetric(mjdCol, metricName='N_visits')
        bundle = metricBundles.MetricBundle(metric, unislicer, sql)
        bundleList.append(bundle)

        # Need pairs in window to get a map of how well it gathered SS pairs.

    # Moon phase.

    metric = metrics.NChangesMetric(col='filter', metricName='Filter Changes')
    bundle = metricBundles.MetricBundle(metric, unislicer, 'night=%i' % night)
    bundleList.append(bundle)

    metric = metrics.BruteOSFMetric()
    bundle = metricBundles.MetricBundle(metric, unislicer, 'night=%i' % night)
    bundleList.append(bundle)

    metric = metrics.MeanMetric('slewTime')
    bundle = metricBundles.MetricBundle(metric, unislicer, 'night=%i' % night)
    bundleList.append(bundle)

    metric = metrics.MinMetric('slewTime')
    bundle = metricBundles.MetricBundle(metric, unislicer, 'night=%i' % night)
    bundleList.append(bundle)

    metric = metrics.MaxMetric('slewTime')
    bundle = metricBundles.MetricBundle(metric, unislicer, 'night=%i' % night)
    bundleList.append(bundle)

    # Make plots of the solar system pairs that were taken in the night
    metric = metrics.PairMetric(mjdCol=mjdCol)
    sql = 'night=%i and (filter ="r" or filter="g" or filter="i")' % night
    bundle = metricBundles.MetricBundle(metric, reg_slicer, sql)
    bundleList.append(bundle)

    metric = metrics.PairMetric(mjdCol=mjdCol, metricName='z Pairs')
    sql = 'night=%i and filter="z"' % night
    bundle = metricBundles.MetricBundle(metric, reg_slicer, sql)
    bundleList.append(bundle)

    # Plot up each visit
    metric = metrics.NightPointingMetric(mjdCol=mjdCol)
    slicer = slicers.UniSlicer()
    sql = 'night=%i' % night
    plotFuncs = [plots.NightPointingPlotter()]
    bundle = metricBundles.MetricBundle(metric,
                                        slicer,
                                        sql,
                                        plotFuncs=plotFuncs)
    bundleList.append(bundle)

    # stats from the note column
    if notes:
        displayDict = {'group': 'Basic Stats', 'subgroup': 'Percent stats'}
        metric = metrics.StringCountMetric(col='note',
                                           percent=True,
                                           metricName='Percents')
        bundle = metricBundles.MetricBundle(metric,
                                            unislicer,
                                            sql,
                                            displayDict=displayDict)
        bundleList.append(bundle)
        displayDict['subgroup'] = 'Count Stats'
        metric = metrics.StringCountMetric(col='note', metricName='Counts')
        bundle = metricBundles.MetricBundle(metric,
                                            unislicer,
                                            sql,
                                            displayDict=displayDict)
        bundleList.append(bundle)

    return metricBundles.makeBundlesDictFromList(bundleList)
Ejemplo n.º 18
0
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))
Ejemplo n.º 19
0
def nvisitsPerProp(opsdb, colmap=None, runName='opsim', binNights=1):
    """Set up a group of all and per-proposal nvisits metrics.

    Parameters
    ----------
    opsdb : lsst.sims.maf.db.Database or lsst.sims.maf.db.OpsimDatabase* object
    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".
    binNights : int, opt
        Number of nights to count in each bin. Default = 1, count number of visits in each night.

    Returns
    -------
    metricBundle
    """
    if colmap is None:
        colmap = getColMap(opsdb)

    propids, proptags = opsdb.fetchPropInfo()

    # Calculate the total number of visits per proposal, and their fraction compared to total.
    totvisits = opsdb.fetchNVisits()
    metric = metrics.CountMetric(colmap['mjd'], metricName='Nvisits')
    slicer = slicers.UniSlicer()
    summaryMetrics = [
        metrics.IdentityMetric(metricName='Count'),
        metrics.NormalizeMetric(normVal=totvisits,
                                metricName='Fraction of total')
    ]
    bundleList = []
    displayDict = {
        'group': 'Visit Summary',
        'subgroup': 'Proposal distribution',
        'order': -1
    }

    bdict = {}
    bdict.update(
        nvisitsPerNight(colmap=colmap,
                        runName=runName,
                        binNights=binNights,
                        sql=None,
                        metadata='All visits'))

    # Look for any multi-proposal groups that we should include.
    for tag in proptags:
        if len(proptags[tag]) > 1:
            pids = proptags[tag]
            sql = '('
            for pid in pids[:-1]:
                sql += 'proposalId=%d or ' % pid
            sql += ' proposalId=%d)' % pids[-1]
            metadata = '%s' % (tag)
            bdict.update(
                nvisitsPerNight(colmap=colmap,
                                runName=runName,
                                binNights=binNights,
                                sql=sql,
                                metadata=metadata))
            displayDict['order'] += 1
            displayDict[
                'caption'] = 'Number of visits and fraction of total visits, for %s.' % metadata
            bundle = mb.MetricBundle(metric,
                                     slicer,
                                     sql=sql,
                                     metadata=metadata,
                                     summaryMetrics=summaryMetrics,
                                     displayDict=displayDict)
            bundleList.append(bundle)

    # And then just run each proposal separately.
    for propid in propids:
        sql = 'proposalId=%d' % (propid)
        metadata = '%s' % (propids[propid])
        bdict.update(
            nvisitsPerNight(colmap=colmap,
                            runName=runName,
                            binNights=binNights,
                            sql=sql,
                            metadata=metadata))
        displayDict['order'] += 1
        displayDict[
            'caption'] = 'Number of visits and fraction of total visits, for %s.' % metadata
        bundle = mb.MetricBundle(metric,
                                 slicer,
                                 constraint=sql,
                                 metadata=metadata,
                                 summaryMetrics=summaryMetrics,
                                 displayDict=displayDict)
        bundleList.append(bundle)

    for b in bundleList:
        b.setRunName(runName)
    bdict.update(mb.makeBundlesDictFromList(bundleList))
    return bdict
Ejemplo n.º 20
0
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
Ejemplo n.º 21
0
def nvisitsPerProp(opsdb,
                   colmap=None,
                   runName='opsim',
                   binNights=1,
                   extraSql=None):
    """Set up a group of all and per-proposal nvisits metrics.

    Parameters
    ----------
    opsdb : lsst.sims.maf.db.Database or lsst.sims.maf.db.OpsimDatabase* object
    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".
    binNights : int, opt
        Number of nights to count in each bin. Default = 1, count number of visits in each night.
    sqlConstraint : str or None, opt
        SQL constraint to add to all metrics.

    Returns
    -------
    metricBundle
    """
    if colmap is None:
        colmap = getColMap(opsdb)

    propids, proptags = opsdb.fetchPropInfo()

    bdict = {}
    bundleList = []

    totvisits = opsdb.fetchNVisits()

    metadata = 'All props'
    if extraSql is not None and len(extraSql) > 0:
        metadata += ' %s' % extraSql
    # Nvisits per night, all proposals.
    bdict.update(
        nvisitsPerNight(colmap=colmap,
                        runName=runName,
                        binNights=binNights,
                        extraSql=extraSql,
                        extraMetadata=metadata,
                        subgroup='All proposals'))
    # Nvisits total, all proposals.
    metric = metrics.CountMetric(colmap['mjd'], metricName='Nvisits')
    slicer = slicers.UniSlicer()
    summaryMetrics = [
        metrics.IdentityMetric(metricName='Count'),
        metrics.NormalizeMetric(normVal=totvisits,
                                metricName='Fraction of total')
    ]
    displayDict = {
        'group': 'Nvisit Summary',
        'subgroup': 'Proposal distribution',
        'order': -1
    }
    displayDict['caption'] = 'Total number of visits for all proposals.'
    if extraSql is not None and len(extraSql) > 0:
        displayDict['caption'] += ' (with constraint %s.)' % extraSql
    bundle = mb.MetricBundle(metric,
                             slicer,
                             extraSql,
                             metadata=metadata,
                             displayDict=displayDict,
                             summaryMetrics=summaryMetrics)
    bundleList.append(bundle)

    # Look for any multi-proposal groups that we should include.
    for tag in proptags:
        if len(proptags[tag]) > 1 or tag in ('WFD', 'DD'):
            pids = proptags[tag]
            sql = '('
            for pid in pids[:-1]:
                sql += '%s=%d or ' % (colmap['proposalId'], pid)
            sql += ' %s=%d)' % (colmap['proposalId'], pids[-1])
            metadata = '%s' % tag
            if extraSql is not None:
                sql = '(%s) and (%s)' % (sql, extraSql)
                metadata += ' %s' % (extraSql)
            bdict.update(
                nvisitsPerNight(colmap=colmap,
                                runName=runName,
                                binNights=binNights,
                                extraSql=sql,
                                extraMetadata=metadata,
                                subgroup=tag))
            displayDict['order'] += 1
            displayDict[
                'caption'] = 'Number of visits and fraction of total visits, for %s.' % metadata
            bundle = mb.MetricBundle(metric,
                                     slicer,
                                     sql,
                                     metadata=metadata,
                                     summaryMetrics=summaryMetrics,
                                     displayDict=displayDict)
            bundleList.append(bundle)

    # And each proposal separately.
    for propid in propids:
        sql = '%s=%d' % (colmap['proposalId'], propid)
        metadata = '%s' % (propids[propid])
        if extraSql is not None:
            sql += ' and (%s)' % (extraSql)
            metadata += ' %s' % extraSql
        bdict.update(
            nvisitsPerNight(colmap=colmap,
                            runName=runName,
                            binNights=binNights,
                            extraSql=sql,
                            extraMetadata=metadata,
                            subgroup='Per proposal'))
        displayDict['order'] += 1
        displayDict[
            'caption'] = 'Number of visits and fraction of total visits, for %s.' % metadata
        bundle = mb.MetricBundle(metric,
                                 slicer,
                                 constraint=sql,
                                 metadata=metadata,
                                 summaryMetrics=summaryMetrics,
                                 displayDict=displayDict)
        bundleList.append(bundle)

    for b in bundleList:
        b.setRunName(runName)
    bdict.update(mb.makeBundlesDictFromList(bundleList))
    return bdict
Ejemplo n.º 22
0
 def testCountMetric(self):
     """Test count metric."""
     testmetric = metrics.CountMetric('testdata')
     self.assertEqual(testmetric.run(self.dv), np.size(self.dv['testdata']))
Ejemplo n.º 23
0
def eastWestBias(colmap=None, runName='opsim', extraSql=None, extraMetadata=None):
    """Plot the number of observations to the east vs to the west, per night.

    Parameters
    ----------
    colmap : dict, 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".
    extraSql : str, opt
        Additional constraint to add to any sql constraints (e.g. 'night<365')
        Default None, for no additional constraints.
    extraMetadata : str, opt
        Additional metadata to add before any below (i.e. "WFD").  Default is None.
    """
    if colmap is None:
        colmap = ColMapDict('opsimV4')
    bundleList = []
    plotBundles = []

    group = 'East vs West'

    subgroup = 'All visits'
    if extraMetadata is not None:
        subgroup = extraMetadata

    displayDict = {'group': group, 'subgroup': subgroup, 'order': 0}

    eastvswest = 180
    if not colmap['raDecDeg']:
        eastvswest = np.radians(eastvswest)

    displayDict['caption'] = 'Number of visits per night that occur with azimuth <= 180.'
    if extraSql is not None:
        displayDict['caption'] += ' With additional sql constraint %s.' % extraSql
    metric = metrics.CountMetric(colmap['night'], metricName='Nvisits East')
    slicer = slicers.OneDSlicer(sliceColName=colmap['night'], binsize=1)
    sql = '%s <= %f' % (colmap['az'], eastvswest)
    if extraSql is not None:
        sql = '(%s) and (%s)' % (sql, extraSql)
    plotDict = {'color': 'orange', 'label': 'East'}
    bundle = mb.MetricBundle(metric, slicer, sql, metadata=extraMetadata,
                             displayDict=displayDict, plotDict=plotDict)
    bundleList.append(bundle)

    displayDict['caption'] = 'Number of visits per night that occur with azimuth > 180.'
    if extraSql is not None:
        displayDict['caption'] += ' With additional sql constraint %s.' % extraSql
    metric = metrics.CountMetric(colmap['night'], metricName='Nvisits West')
    slicer = slicers.OneDSlicer(sliceColName=colmap['night'], binsize=1)
    sql = '%s > %f' % (colmap['az'], eastvswest)
    if extraSql is not None:
        sql = '(%s) and (%s)' % (sql, extraSql)
    plotDict = {'color': 'blue', 'label': 'West'}
    bundle = mb.MetricBundle(metric, slicer, sql, metadata=extraMetadata,
                             displayDict=displayDict, plotDict=plotDict)
    bundleList.append(bundle)

    # Set the runName for all bundles and return the bundleDict.
    for b in bundleList:
        b.setRunName(runName)
    return mb.makeBundlesDictFromList(bundleList), plotBundles
Ejemplo n.º 24
0
def slewBasics(colmap=None, runName='opsim', sqlConstraint=None):
    """Generate a simple set of statistics about the slew times and distances.
    These slew statistics can be run on the summary or default tables.

    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".
    sqlConstraint : str or None, opt
        SQL constraint to add to metrics. (note this runs on summary table).

    Returns
    -------
    metricBundleDict
    """

    if colmap is None:
        colmap = ColMapDict('opsimV4')

    bundleList = []

    # Calculate basic stats on slew times. (mean/median/min/max + total).
    slicer = slicers.UniSlicer()

    metadata = 'All visits'
    displayDict = {
        'group': 'Slew',
        'subgroup': 'Slew Basics',
        'order': -1,
        'caption': None
    }
    # Add total number of slews.
    metric = metrics.CountMetric(colmap['slewtime'], metricName='Slew Count')
    displayDict['caption'] = 'Total number of slews recorded in summary table.'
    displayDict['order'] += 1
    bundle = mb.MetricBundle(metric,
                             slicer,
                             sqlConstraint,
                             metadata=metadata,
                             displayDict=displayDict)
    bundleList.append(bundle)
    for metric in standardMetrics(colmap['slewtime']):
        displayDict['caption'] = '%s in seconds.' % (metric.name)
        displayDict['order'] += 1
        bundle = mb.MetricBundle(metric,
                                 slicer,
                                 sqlConstraint,
                                 metadata=metadata,
                                 displayDict=displayDict)
        bundleList.append(bundle)

    # Slew Time histogram.
    slicer = slicers.OneDSlicer(sliceColName=colmap['slewtime'], binsize=2)
    metric = metrics.CountMetric(col=colmap['slewtime'],
                                 metricName='Slew Time Histogram')
    metadata = 'All visits'
    plotDict = {'logScale': True, 'ylabel': 'Count'}
    displayDict[
        'caption'] = 'Histogram of slew times (seconds) for all visits.'
    displayDict['order'] += 1
    bundle = mb.MetricBundle(metric,
                             slicer,
                             sqlConstraint,
                             metadata=metadata,
                             plotDict=plotDict,
                             displayDict=displayDict)
    bundleList.append(bundle)

    # Slew distance histogram, if available.
    if colmap['slewdist'] is not None:
        slicer = slicers.OneDSlicer(sliceColName=colmap['slewdist'])
        metric = metrics.CountMetric(col=colmap['slewdist'],
                                     metricName='Slew Distance Histogram')
        plotDict = {'logScale': True, 'ylabel': 'Count'}
        displayDict[
            'caption'] = 'Histogram of slew distances (angle) for all visits.'
        displayDict['order'] += 1
        bundle = mb.MetricBundle(metric,
                                 slicer,
                                 sqlConstraint,
                                 metadata=metadata,
                                 plotDict=plotDict,
                                 displayDict=displayDict)
        bundleList.append(bundle)

    # Set the runName for all bundles and return the bundleDict.
    for b in bundleList:
        b.setRunName(runName)
    return mb.makeBundlesDictFromList(bundleList)
Ejemplo n.º 25
0
def makeBundleList(dbFile,
                   night=1,
                   nside=64,
                   latCol='ditheredDec',
                   lonCol='ditheredRA'):
    """
    Make a bundleList of things to run
    """

    # Construct sql queries for each filter and all filters
    filters = ['u', 'g', 'r', 'i', 'z', 'y']
    sqls = ['night=%i and filter="%s"' % (night, f) for f in filters]
    sqls.append('night=%i' % night)

    bundleList = []
    plotFuncs_lam = [plots.LambertSkyMap()]

    reg_slicer = slicers.HealpixSlicer(nside=nside,
                                       lonCol=lonCol,
                                       latCol=latCol,
                                       latLonDeg=False)
    altaz_slicer = slicers.HealpixSlicer(nside=nside,
                                         latCol='altitude',
                                         latLonDeg=False,
                                         lonCol='azimuth',
                                         useCache=False)

    unislicer = slicers.UniSlicer()
    for sql in sqls:

        # Number of exposures
        metric = metrics.CountMetric('expMJD', metricName='N visits')
        bundle = metricBundles.MetricBundle(metric, reg_slicer, sql)
        bundleList.append(bundle)
        metric = metrics.CountMetric('expMJD', metricName='N visits alt az')
        bundle = metricBundles.MetricBundle(metric,
                                            altaz_slicer,
                                            sql,
                                            plotFuncs=plotFuncs_lam)
        bundleList.append(bundle)

        metric = metrics.MeanMetric('expMJD', metricName='Mean Visit Time')
        bundle = metricBundles.MetricBundle(metric, reg_slicer, sql)
        bundleList.append(bundle)
        metric = metrics.MeanMetric('expMJD',
                                    metricName='Mean Visit Time alt az')
        bundle = metricBundles.MetricBundle(metric,
                                            altaz_slicer,
                                            sql,
                                            plotFuncs=plotFuncs_lam)
        bundleList.append(bundle)

        metric = metrics.CountMetric('expMJD', metricName='N_visits')
        bundle = metricBundles.MetricBundle(metric, unislicer, sql)
        bundleList.append(bundle)

        # Need pairs in window to get a map of how well it gathered SS pairs.

    # Moon phase.

    metric = metrics.NChangesMetric(col='filter', metricName='Filter Changes')
    bundle = metricBundles.MetricBundle(metric, unislicer, 'night=%i' % night)
    bundleList.append(bundle)

    metric = metrics.OpenShutterFractionMetric()
    bundle = metricBundles.MetricBundle(metric, unislicer, 'night=%i' % night)
    bundleList.append(bundle)

    metric = metrics.MeanMetric('slewTime')
    bundle = metricBundles.MetricBundle(metric, unislicer, 'night=%i' % night)
    bundleList.append(bundle)

    metric = metrics.MinMetric('slewTime')
    bundle = metricBundles.MetricBundle(metric, unislicer, 'night=%i' % night)
    bundleList.append(bundle)

    metric = metrics.MaxMetric('slewTime')
    bundle = metricBundles.MetricBundle(metric, unislicer, 'night=%i' % night)
    bundleList.append(bundle)

    # Make plots of the solar system pairs that were taken in the night
    metric = metrics.PairMetric()
    sql = 'night=%i and (filter ="r" or filter="g" or filter="i")' % night
    bundle = metricBundles.MetricBundle(metric, reg_slicer, sql)
    bundleList.append(bundle)

    metric = metrics.PairMetric(metricName='z Pairs')
    sql = 'night=%i and filter="z"' % night
    bundle = metricBundles.MetricBundle(metric, reg_slicer, sql)
    bundleList.append(bundle)

    # Plot up each visit
    metric = metrics.NightPointingMetric()
    slicer = slicers.UniSlicer()
    sql = sql = 'night=%i' % night
    plotFuncs = [plots.NightPointingPlotter()]
    bundle = metricBundles.MetricBundle(metric,
                                        slicer,
                                        sql,
                                        plotFuncs=plotFuncs)
    bundleList.append(bundle)

    return metricBundles.makeBundlesDictFromList(bundleList)
Ejemplo n.º 26
0
# UniSlicer
slicer = slicers.UniSlicer()
metric = metrics.MeanMetric(col='airmass')
bundle = metricBundles.MetricBundle(metric, slicer, sqlWhere)
bundleList.append(bundle)

# HealpixSlicer
slicer = slicers.HealpixSlicer(nside=16)
metric = metrics.MeanMetric(col='airmass', metricName='MeanAirmass_heal')
bundle = metricBundles.MetricBundle(metric, slicer, sqlWhere)
bundleList.append(bundle)

# OneDSlicer
slicer = slicers.OneDSlicer(sliceColName='night', binsize=10)
metric = metrics.CountMetric(col='expMJD')
bundle = metricBundles.MetricBundle(metric, slicer, sqlWhere)
bundleList.append(bundle)

# OpsimFieldSlicer
slicer = slicers.OpsimFieldSlicer()
metric = metrics.MeanMetric(col='airmass')
bundle = metricBundles.MetricBundle(metric, slicer, sqlWhere)
bundleList.append(bundle)

# UserPointsSlicer
ra = np.arange(0, 101, 1) / 100. * np.pi
dec = np.arange(0, 101, 1) / 100. * (-np.pi)
slicer = slicers.UserPointsSlicer(ra=ra, dec=dec)
metric = metrics.MeanMetric(col='airmass', metricName='meanAirmass_user')
bundle = metricBundles.MetricBundle(metric, slicer, sqlWhere)