def testDustMap(self): mapPath = os.environ['SIMS_MAPS_DIR'] if os.path.isfile(os.path.join(mapPath, 'DustMaps/dust_nside_128.npz')): data = makeDataValues() dustmap = maps.DustMap() slicer1 = slicers.HealpixSlicer() slicer1.setupSlicer(data) result1 = dustmap.run(slicer1.slicePoints) assert ('ebv' in list(result1.keys())) fieldData = makeFieldData() slicer2 = slicers.OpsimFieldSlicer() slicer2.setupSlicer(data, fieldData) result2 = dustmap.run(slicer2.slicePoints) assert ('ebv' in list(result2.keys())) # Check interpolation works dustmap = maps.DustMap(interp=True) result3 = dustmap.run(slicer2.slicePoints) assert ('ebv' in list(result3.keys())) # Check warning gets raised dustmap = maps.DustMap(nside=4) with warnings.catch_warnings(record=True) as w: warnings.simplefilter("always") dustmap.run(slicer1.slicePoints) self.assertTrue("nside" in str(w[-1].message)) else: warnings.warn('Did not find dustmaps, not running testMaps.py')
def tdcBatch(colmap=None, runName='opsim', nside=64, extraSql=None, extraMetadata=None): # The options to add additional sql constraints are removed for now. if colmap is None: colmap = ColMapDict('fbs') # Calculate a subset of DESC WFD-related metrics. displayDict = {'group': 'Strong Lensing'} displayDict['subgroup'] = 'Lens Time Delay' subsetPlots = [plots.HealpixSkyMap(), plots.HealpixHistogram()] summaryMetrics = [ metrics.MeanMetric(), metrics.MedianMetric(), metrics.RmsMetric() ] # Ideally need a way to do better on calculating the summary metrics for the high accuracy area. slicer = slicers.HealpixSlicer(nside=nside, useCache=False) tdcMetric = metrics.TdcMetric(metricName='TDC', mjdCol=colmap['mjd'], nightCol=colmap['night'], filterCol=colmap['filter'], m5Col=colmap['fiveSigmaDepth']) dustmap = maps.DustMap(nside=nside, interp=False) bundle = mb.MetricBundle(tdcMetric, slicer, constraint=extraSql, metadata=extraMetadata, displayDict=displayDict, plotFuncs=subsetPlots, mapsList=[dustmap], summaryMetrics=summaryMetrics) bundleList = [bundle] # Set the runName for all bundles and return the bundleDict. for b in bundleList: b.setRunName(runName) return mb.makeBundlesDictFromList(bundleList)
def coaddM5Analysis(path, dbfile, runName, slair=False, WFDandDDFs=False, noDithOnly=False, bestDithOnly=False, someDithOnly=False, specifiedDith=None, nside=128, filterBand='r', includeDustExtinction=False, saveunMaskedCoaddData=False, pixelRadiusForMasking=5, cutOffYear=None, plotSkymap=True, plotCartview=True, unmaskedColorMin=None, unmaskedColorMax=None, maskedColorMin=None, maskedColorMax=None, nTicks=5, plotPowerSpectrum=True, showPlots=True, saveFigs=True, almAnalysis=True, raRange=[-50, 50], decRange=[-65, 5], saveMaskedCoaddData=True): """ Analyze the artifacts induced in the coadded 5sigma depth due to imperfect observing strategy. - Creates an output directory for subdirectories containing the specified things to save. - Creates, shows, and saves comparison plots. - Returns the metricBundle object containing the calculated coadded depth, and the output directory name. Required Parameters ------------------- * path: str: path to the main directory where output directory is to be saved. * dbfile: str: path to the OpSim output file, e.g. to a copy of enigma_1189 * runName: str: run name tag to identify the output of specified OpSim output, e.g. 'enigma1189' Optional Parameters ------------------- * slair: boolean: set to True if analysis on a SLAIR output. Default: False * WFDandDDFs: boolean: set to True if want to consider both WFD survet and DDFs. Otherwise will only work with WFD. Default: False * noDithOnly: boolean: set to True if only want to consider the undithered survey. Default: False * bestDithOnly: boolean: set to True if only want to consider RandomDitherFieldPerVisit. Default: False * someDithOnly: boolean: set to True if only want to consider undithered and a few dithered surveys. Default: False * specifiedDith: str: specific dither strategy to run. Default: None * nside: int: HEALpix resolution parameter. Default: 128 * filterBand: str: any one of 'u', 'g', 'r', 'i', 'z', 'y'. Default: 'r' * includeDustExtinction: boolean: set to include dust extinction. Default: False * saveunMaskedCoaddData: boolean: set to True to save data before border masking. Default: False * pixelRadiusForMasking: int: number of pixels to mask along the shallow border. Default: 5 * cutOffYear: int: year cut to restrict analysis to only a subset of the survey. Must range from 1 to 9, or None for the full survey analysis (10 yrs). Default: None * plotSkymap: boolean: set to True if want to plot skymaps. Default: True * plotCartview: boolean: set to True if want to plot cartview plots. Default: False * unmaskedColorMin: float: lower limit on the colorscale for unmasked skymaps. Default: None * unmaskedColorMax: float: upper limit on the colorscale for unmasked skymaps. Default: None * maskedColorMin: float: lower limit on the colorscale for border-masked skymaps. Default: None * maskedColorMax: float: upper limit on the colorscale for border-masked skymaps. Default: None * nTicks: int: (number of ticks - 1) on the skymap colorbar. Default: 5 * plotPowerSpectrum: boolean: set to True if want to plot powerspectra. Default: True * showPlots: boolean: set to True if want to show figures. Default: True * saveFigs: boolean: set to True if want to save figures. Default: True * almAnalysis: boolean: set to True to perform the alm analysis. Default: True * raRange: float array: range of right ascention (in degrees) to consider in alm cartview plot; applicable when almAnalysis=True. Default: [-50,50] * decRange: float array: range of declination (in degrees) to consider in alm cartview plot; applicable when almAnalysis=True. Default: [-65,5] * saveMaskedCoaddData: boolean: set to True to save the coadded depth data after the border masking. Default: True """ # ------------------------------------------------------------------------ # read in the database if slair: # slair database opsdb = db.Database(dbfile, defaultTable='observations') else: # OpSim database opsdb = db.OpsimDatabase(dbfile) # ------------------------------------------------------------------------ # set up the outDir zeropt_tag = '' if cutOffYear is not None: zeropt_tag = '%syearCut' % cutOffYear else: zeropt_tag = 'fullSurveyPeriod' if includeDustExtinction: dust_tag = 'withDustExtinction' else: dust_tag = 'noDustExtinction' regionType = '' if WFDandDDFs: regionType = 'WFDandDDFs_' outDir = 'coaddM5Analysis_%snside%s_%s_%spixelRadiusForMasking_%sBand_%s_%s_directory' % ( regionType, nside, dust_tag, pixelRadiusForMasking, filterBand, runName, zeropt_tag) print('# outDir: %s' % outDir) resultsDb = db.ResultsDb(outDir=outDir) # ------------------------------------------------------------------------ # set up the sql constraint if WFDandDDFs: if cutOffYear is not None: nightCutOff = (cutOffYear) * 365.25 sqlconstraint = 'night<=%s and filter=="%s"' % (nightCutOff, filterBand) else: sqlconstraint = 'filter=="%s"' % filterBand else: # set up the propID and units on the ra, dec if slair: # no prop ID; only WFD is simulated. wfdWhere = '' raDecInDeg = True else: propIds, propTags = opsdb.fetchPropInfo() wfdWhere = '%s and ' % opsdb.createSQLWhere('WFD', propTags) raDecInDeg = opsdb.raDecInDeg # set up the year cutoff if cutOffYear is not None: nightCutOff = (cutOffYear) * 365.25 sqlconstraint = '%snight<=%s and filter=="%s"' % ( wfdWhere, nightCutOff, filterBand) else: sqlconstraint = '%sfilter=="%s"' % (wfdWhere, filterBand) print('# sqlconstraint: %s' % sqlconstraint) # ------------------------------------------------------------------------ # setup all the slicers slicer = {} stackerList = {} if specifiedDith is not None: # would like to add all the stackers first and then keep only the one that is specified bestDithOnly, noDithOnly = False, False if bestDithOnly: stackerList['RandomDitherFieldPerVisit'] = [ mafStackers.RandomDitherFieldPerVisitStacker(degrees=raDecInDeg, randomSeed=1000) ] slicer['RandomDitherFieldPerVisit'] = slicers.HealpixSlicer( lonCol='randomDitherFieldPerVisitRa', latCol='randomDitherFieldPerVisitDec', latLonDeg=raDecInDeg, nside=nside, useCache=False) else: if slair: slicer['NoDither'] = slicers.HealpixSlicer(lonCol='RA', latCol='dec', latLonDeg=raDecInDeg, nside=nside, useCache=False) else: slicer['NoDither'] = slicers.HealpixSlicer(lonCol='fieldRA', latCol='fieldDec', latLonDeg=raDecInDeg, nside=nside, useCache=False) if someDithOnly and not noDithOnly: #stackerList['RepulsiveRandomDitherFieldPerVisit'] = [myStackers.RepulsiveRandomDitherFieldPerVisitStacker(degrees=raDecInDeg, # randomSeed=1000)] #slicer['RepulsiveRandomDitherFieldPerVisit'] = slicers.HealpixSlicer(lonCol='repulsiveRandomDitherFieldPerVisitRa', # latCol='repulsiveRandomDitherFieldPerVisitDec', # latLonDeg=raDecInDeg, nside=nside, # useCache=False) slicer['SequentialHexDitherFieldPerNight'] = slicers.HealpixSlicer( lonCol='hexDitherFieldPerNightRa', latCol='hexDitherFieldPerNightDec', latLonDeg=raDecInDeg, nside=nside, useCache=False) slicer['PentagonDitherPerSeason'] = slicers.HealpixSlicer( lonCol='pentagonDitherPerSeasonRa', latCol='pentagonDitherPerSeasonDec', latLonDeg=raDecInDeg, nside=nside, useCache=False) elif not noDithOnly: # random dithers on different timescales stackerList['RandomDitherPerNight'] = [ mafStackers.RandomDitherPerNightStacker(degrees=raDecInDeg, randomSeed=1000) ] stackerList['RandomDitherFieldPerNight'] = [ mafStackers.RandomDitherFieldPerNightStacker( degrees=raDecInDeg, randomSeed=1000) ] stackerList['RandomDitherFieldPerVisit'] = [ mafStackers.RandomDitherFieldPerVisitStacker( degrees=raDecInDeg, randomSeed=1000) ] # rep random dithers on different timescales #stackerList['RepulsiveRandomDitherPerNight'] = [myStackers.RepulsiveRandomDitherPerNightStacker(degrees=raDecInDeg, # randomSeed=1000)] #stackerList['RepulsiveRandomDitherFieldPerNight'] = [myStackers.RepulsiveRandomDitherFieldPerNightStacker(degrees=raDecInDeg, # randomSeed=1000)] #stackerList['RepulsiveRandomDitherFieldPerVisit'] = [myStackers.RepulsiveRandomDitherFieldPerVisitStacker(degrees=raDecInDeg, # randomSeed=1000)] # set up slicers for different dithers # random dithers on different timescales slicer['RandomDitherPerNight'] = slicers.HealpixSlicer( lonCol='randomDitherPerNightRa', latCol='randomDitherPerNightDec', latLonDeg=raDecInDeg, nside=nside, useCache=False) slicer['RandomDitherFieldPerNight'] = slicers.HealpixSlicer( lonCol='randomDitherFieldPerNightRa', latCol='randomDitherFieldPerNightDec', latLonDeg=raDecInDeg, nside=nside, useCache=False) slicer['RandomDitherFieldPerVisit'] = slicers.HealpixSlicer( lonCol='randomDitherFieldPerVisitRa', latCol='randomDitherFieldPerVisitDec', latLonDeg=raDecInDeg, nside=nside, useCache=False) # rep random dithers on different timescales #slicer['RepulsiveRandomDitherPerNight'] = slicers.HealpixSlicer(lonCol='repulsiveRandomDitherPerNightRa', # latCol='repulsiveRandomDitherPerNightDec', # latLonDeg=raDecInDeg, nside=nside, useCache=False) #slicer['RepulsiveRandomDitherFieldPerNight'] = slicers.HealpixSlicer(lonCol='repulsiveRandomDitherFieldPerNightRa', # latCol='repulsiveRandomDitherFieldPerNightDec', # latLonDeg=raDecInDeg, nside=nside, # useCache=False) #slicer['RepulsiveRandomDitherFieldPerVisit'] = slicers.HealpixSlicer(lonCol='repulsiveRandomDitherFieldPerVisitRa', # latCol='repulsiveRandomDitherFieldPerVisitDec', # latLonDeg=raDecInDeg, nside=nside, # useCache=False) # spiral dithers on different timescales slicer['FermatSpiralDitherPerNight'] = slicers.HealpixSlicer( lonCol='fermatSpiralDitherPerNightRa', latCol='fermatSpiralDitherPerNightDec', latLonDeg=raDecInDeg, nside=nside, useCache=False) slicer['FermatSpiralDitherFieldPerNight'] = slicers.HealpixSlicer( lonCol='fermatSpiralDitherFieldPerNightRa', latCol='fermatSpiralDitherFieldPerNightDec', latLonDeg=raDecInDeg, nside=nside, useCache=False) slicer['FermatSpiralDitherFieldPerVisit'] = slicers.HealpixSlicer( lonCol='fermatSpiralDitherFieldPerVisitRa', latCol='fermatSpiralDitherFieldPerVisitDec', latLonDeg=raDecInDeg, nside=nside, useCache=False) # hex dithers on different timescales slicer['SequentialHexDitherPerNight'] = slicers.HealpixSlicer( lonCol='hexDitherPerNightRa', latCol='hexDitherPerNightDec', latLonDeg=raDecInDeg, nside=nside, useCache=False) slicer['SequentialHexDitherFieldPerNight'] = slicers.HealpixSlicer( lonCol='hexDitherFieldPerNightRa', latCol='hexDitherFieldPerNightDec', latLonDeg=raDecInDeg, nside=nside, useCache=False) slicer['SequentialHexDitherFieldPerVisit'] = slicers.HealpixSlicer( lonCol='hexDitherFieldPerVisitRa', latCol='hexDitherFieldPerVisitDec', latLonDeg=raDecInDeg, nside=nside, useCache=False) # per season dithers slicer['PentagonDitherPerSeason'] = slicers.HealpixSlicer( lonCol='pentagonDitherPerSeasonRa', latCol='pentagonDitherPerSeasonDec', latLonDeg=raDecInDeg, nside=nside, useCache=False) slicer['PentagonDiamondDitherPerSeason'] = slicers.HealpixSlicer( lonCol='pentagonDiamondDitherPerSeasonRa', latCol='pentagonDiamondDitherPerSeasonDec', latLonDeg=raDecInDeg, nside=nside, useCache=False) slicer['SpiralDitherPerSeason'] = slicers.HealpixSlicer( lonCol='spiralDitherPerSeasonRa', latCol='spiralDitherPerSeasonDec', latLonDeg=raDecInDeg, nside=nside, useCache=False) if specifiedDith is not None: stackerList_, slicer_ = {}, {} if specifiedDith in slicer.keys(): if specifiedDith.__contains__( 'Random' ): # only Random dithers have a stacker object for rand seed specification stackerList_[specifiedDith] = stackerList[specifiedDith] slicer_[specifiedDith] = slicer[specifiedDith] else: raise ValueError( 'Invalid value for specifiedDith: %s. Allowed values include one of the following:\n%s' % (specifiedDith, slicer.keys())) stackerList, slicer = stackerList_, slicer_ # ------------------------------------------------------------------------ if slair: m5Col = 'fivesigmadepth' else: m5Col = 'fiveSigmaDepth' # set up the metric if includeDustExtinction: # include dust extinction when calculating the co-added depth coaddMetric = metrics.ExgalM5(m5Col=m5Col, lsstFilter=filterBand) else: coaddMetric = metrics.Coaddm5Metric(m5col=m5col) dustMap = maps.DustMap( interp=False, nside=nside ) # include dustMap; actual in/exclusion of dust is handled by the galaxyCountMetric # ------------------------------------------------------------------------ # set up the bundle coaddBundle = {} for dither in slicer: if dither in stackerList: coaddBundle[dither] = metricBundles.MetricBundle( coaddMetric, slicer[dither], sqlconstraint, stackerList=stackerList[dither], runName=runName, metadata=dither, mapsList=[dustMap]) else: coaddBundle[dither] = metricBundles.MetricBundle( coaddMetric, slicer[dither], sqlconstraint, runName=runName, metadata=dither, mapsList=[dustMap]) # ------------------------------------------------------------------------ # run the analysis if includeDustExtinction: print('\n# Running coaddBundle with dust extinction ...') else: print('\n# Running coaddBundle without dust extinction ...') cGroup = metricBundles.MetricBundleGroup(coaddBundle, opsdb, outDir=outDir, resultsDb=resultsDb, saveEarly=False) cGroup.runAll() # ------------------------------------------------------------------------ # plot and save the data plotBundleMaps(path, outDir, coaddBundle, dataLabel='$%s$-band Coadded Depth' % filterBand, filterBand=filterBand, dataName='%s-band Coadded Depth' % filterBand, skymap=plotSkymap, powerSpectrum=plotPowerSpectrum, cartview=plotCartview, colorMin=unmaskedColorMin, colorMax=unmaskedColorMax, nTicks=nTicks, showPlots=showPlots, saveFigs=saveFigs, outDirNameForSavedFigs='coaddM5Plots_unmaskedBorders') print('\n# Done saving plots without border masking.\n') # ------------------------------------------------------------------------ plotHandler = plots.PlotHandler(outDir=outDir, resultsDb=resultsDb, thumbnail=False, savefig=False) print( '# Number of pixels in the survey region (before masking the border):') for dither in coaddBundle: print( ' %s: %s' % (dither, len(np.where(coaddBundle[dither].metricValues.mask == False)[0]))) # ------------------------------------------------------------------------ # save the unmasked data? if saveunMaskedCoaddData: outDir_new = 'unmaskedCoaddData' if not os.path.exists('%s%s/%s' % (path, outDir, outDir_new)): os.makedirs('%s%s/%s' % (path, outDir, outDir_new)) saveBundleData_npzFormat('%s%s/%s' % (path, outDir, outDir_new), coaddBundle, 'coaddM5Data_unmasked', filterBand) # ------------------------------------------------------------------------ # mask the edges print('\n# Masking the edges for coadd ...') coaddBundle = maskingAlgorithmGeneralized( coaddBundle, plotHandler, dataLabel='$%s$-band Coadded Depth' % filterBand, nside=nside, pixelRadius=pixelRadiusForMasking, plotIntermediatePlots=False, plotFinalPlots=False, printFinalInfo=True) if (pixelRadiusForMasking > 0): # plot and save the masked data plotBundleMaps(path, outDir, coaddBundle, dataLabel='$%s$-band Coadded Depth' % filterBand, filterBand=filterBand, dataName='%s-band Coadded Depth' % filterBand, skymap=plotSkymap, powerSpectrum=plotPowerSpectrum, cartview=plotCartview, colorMin=maskedColorMin, colorMax=maskedColorMax, nTicks=nTicks, showPlots=showPlots, saveFigs=saveFigs, outDirNameForSavedFigs='coaddM5Plots_maskedBorders') print('\n# Done saving plots with border masking. \n') # ------------------------------------------------------------------------ # Calculate total power summarymetric = metrics.TotalPowerMetric() for dither in coaddBundle: coaddBundle[dither].setSummaryMetrics(summarymetric) coaddBundle[dither].computeSummaryStats() print('# Total power for %s case is %f.' % (dither, coaddBundle[dither].summaryValues['TotalPower'])) print('') # ------------------------------------------------------------------------ # run the alm analysis if almAnalysis: almPlots(path, outDir, copy.deepcopy(coaddBundle), nside=nside, filterband=filterBand, raRange=raRange, decRange=decRange, showPlots=showPlots) # ------------------------------------------------------------------------ # save the masked data? if saveMaskedCoaddData and (pixelRadiusForMasking > 0): outDir_new = 'maskedCoaddData' if not os.path.exists('%s%s/%s' % (path, outDir, outDir_new)): os.makedirs('%s%s/%s' % (path, outDir, outDir_new)) saveBundleData_npzFormat('%s%s/%s' % (path, outDir, outDir_new), coaddBundle, 'coaddM5Data_masked', filterBand) # ------------------------------------------------------------------------ # plot comparison plots if len(coaddBundle.keys()) > 1: # more than one key # set up the directory outDir_comp = 'coaddM5ComparisonPlots' if not os.path.exists('%s%s/%s' % (path, outDir, outDir_comp)): os.makedirs('%s%s/%s' % (path, outDir, outDir_comp)) # ------------------------------------------------------------------------ # plot for the power spectra cl = {} for dither in plotColor: if dither in coaddBundle: cl[dither] = hp.anafast(hp.remove_dipole( coaddBundle[dither].metricValues.filled( coaddBundle[dither].slicer.badval)), lmax=500) ell = np.arange(np.size(cl[dither])) plt.plot(ell, (cl[dither] * ell * (ell + 1)) / 2.0 / np.pi, color=plotColor[dither], linestyle='-', label=dither) plt.xlabel(r'$\ell$') plt.ylabel(r'$\ell(\ell+1)C_\ell/(2\pi)$') plt.xlim(0, 500) fig = plt.gcf() fig.set_size_inches(12.5, 10.5) leg = plt.legend(labelspacing=0.001) for legobj in leg.legendHandles: legobj.set_linewidth(4.0) filename = 'powerspectrum_comparison_all.png' plt.savefig('%s%s/%s/%s' % (path, outDir, outDir_comp, filename), bbox_inches='tight', format='png') plt.show() # create the histogram scale = hp.nside2pixarea(nside, degrees=True) def tickFormatter(y, pos): return '%d' % (y * scale) # convert pixel count to area binsize = 0.01 for dither in plotColor: if dither in coaddBundle: ind = np.where( coaddBundle[dither].metricValues.mask == False)[0] binAll = int( (max(coaddBundle[dither].metricValues.data[ind]) - min(coaddBundle[dither].metricValues.data[ind])) / binsize) plt.hist(coaddBundle[dither].metricValues.data[ind], bins=binAll, label=dither, histtype='step', color=plotColor[dither]) ax = plt.gca() ymin, ymax = ax.get_ylim() nYticks = 10. wantedYMax = ymax * scale wantedYMax = 10. * np.ceil(float(wantedYMax) / 10.) increment = 5. * np.ceil(float(wantedYMax / nYticks) / 5.) wantedArray = np.arange(0, wantedYMax, increment) ax.yaxis.set_ticks(wantedArray / scale) ax.yaxis.set_major_formatter(FuncFormatter(tickFormatter)) plt.xlabel('$%s$-band Coadded Depth' % filterBand) plt.ylabel('Area (deg$^2$)') fig = plt.gcf() fig.set_size_inches(12.5, 10.5) leg = plt.legend(labelspacing=0.001, loc=2) for legobj in leg.legendHandles: legobj.set_linewidth(2.0) filename = 'histogram_comparison.png' plt.savefig('%s%s/%s/%s' % (path, outDir, outDir_comp, filename), bbox_inches='tight', format='png') plt.show() # ------------------------------------------------------------------------ # plot power spectra for the separte panel totKeys = len(list(coaddBundle.keys())) if (totKeys > 1): plt.clf() nCols = 2 nRows = int(np.ceil(float(totKeys) / nCols)) fig, ax = plt.subplots(nRows, nCols) plotRow = 0 plotCol = 0 for dither in list(plotColor.keys()): if dither in list(coaddBundle.keys()): ell = np.arange(np.size(cl[dither])) ax[plotRow, plotCol].plot(ell, (cl[dither] * ell * (ell + 1)) / 2.0 / np.pi, color=plotColor[dither], label=dither) if (plotRow == nRows - 1): ax[plotRow, plotCol].set_xlabel(r'$\ell$') ax[plotRow, plotCol].set_ylabel(r'$\ell(\ell+1)C_\ell/(2\pi)$') ax[plotRow, plotCol].yaxis.set_major_locator(MaxNLocator(3)) if (dither != 'NoDither'): ax[plotRow, plotCol].set_ylim(0, 0.0035) ax[plotRow, plotCol].set_xlim(0, 500) plotRow += 1 if (plotRow > nRows - 1): plotRow = 0 plotCol += 1 fig.set_size_inches(20, int(nRows * 30 / 7.)) filename = 'powerspectrum_sepPanels.png' plt.savefig('%s%s/%s/%s' % (path, outDir, outDir_comp, filename), bbox_inches='tight', format='png') plt.show() return coaddBundle, outDir
def descWFDBatch(colmap=None, runName='opsim', nside=64, bandpass='******', nfilters_needed=6, lim_ebv=0.2, mag_cuts = {1: 24.75 - 0.1, 3: 25.35 - 0.1, 6: 25.72 - 0.1, 10: 26.0 - 0.1}): # Hide some dependencies .. we should probably bring these into MAF from mafContrib.lssmetrics.depthLimitedNumGalMetric import DepthLimitedNumGalMetric from mafContrib import (Plasticc_metric, plasticc_slicer, load_plasticc_lc) # The options to add additional sql constraints are removed for now. if colmap is None: colmap = ColMapDict('fbs') # Calculate a subset of DESC WFD-related metrics. displayDict = {'group': 'Cosmology'} subgroupCount = 1 standardStats = standardSummary(withCount=False) subsetPlots = [plots.HealpixSkyMap(), plots.HealpixHistogram()] if not isinstance(mag_cuts, dict): if isinstance(mag_cuts, float) or isinstance(mag_cuts, int): mag_cuts = {10: mag_cuts} else: raise TypeError() yrs = list(mag_cuts.keys()) maxYr = max(yrs) # Load up the plastic light curves models = ['SNIa-normal'] plasticc_models_dict = {} for model in models: plasticc_models_dict[model] = list(load_plasticc_lc(model=model).values()) # One of the primary concerns for DESC WFD metrics is to add dust extinction and coadded depth limits # as well as to get some coverage in all 6 bandpasses. # These cuts figure into many of the general metrics. displayDict['subgroup'] = f'{subgroupCount}: Static Science' ## Static Science # Calculate the static science metrics - effective survey area, mean/median coadded depth, stdev of # coadded depth and the 3x2ptFoM emulator. dustmap = maps.DustMap(nside=nside, interp=False) pix_area = hp.nside2pixarea(nside, degrees=True) summaryMetrics = [metrics.MeanMetric(), metrics.MedianMetric(), metrics.RmsMetric(), metrics.CountRatioMetric(normVal=1/pix_area, metricName='Effective Area (deg)')] bundleList = [] displayDict['order'] = 0 for yr_cut in yrs: ptsrc_lim_mag_i_band = mag_cuts[yr_cut] sqlconstraint = 'night <= %s' % (yr_cut * 365.25) sqlconstraint += ' and note not like "DD%"' metadata = f'{bandpass} band non-DD year {yr_cut}' ThreebyTwoSummary = metrics.StaticProbesFoMEmulatorMetricSimple(nside=nside, year=yr_cut, metricName='3x2ptFoM') print(colmap['fiveSigmaDepth'], colmap['filter']) m = metrics.ExgalM5_with_cuts(m5Col=colmap['fiveSigmaDepth'], filterCol=colmap['filter'], lsstFilter=bandpass, nFilters=nfilters_needed, extinction_cut=lim_ebv, depth_cut=ptsrc_lim_mag_i_band) s = slicers.HealpixSlicer(nside=nside, useCache=False) caption = f'Cosmology/Static Science metrics are based on evaluating the region of ' caption += f'the sky that meets the requirements (in year {yr_cut} of coverage in ' caption += f'all {nfilters_needed}, a lower E(B-V) value than {lim_ebv}, and at ' caption += f'least a coadded depth of {ptsrc_lim_mag_i_band} in {bandpass}. ' caption += f'From there the effective survey area, coadded depth, standard deviation of the depth, ' caption += f'and a 3x2pt static science figure of merit emulator are calculated using the ' caption += f'dust-extincted coadded depth map (over that reduced footprint).' displayDict['caption'] = caption bundle = mb.MetricBundle(m, s, sqlconstraint, mapsList=[dustmap], metadata=metadata, summaryMetrics=summaryMetrics + [ThreebyTwoSummary], displayDict=displayDict) displayDict['order'] += 1 bundleList.append(bundle) ## LSS Science # The only metric we have from LSS is the NGals metric - which is similar to the GalaxyCountsExtended # metric, but evaluated only on the depth/dust cuts footprint. subgroupCount += 1 displayDict['subgroup'] = f'{subgroupCount}: LSS' displayDict['order'] = 0 plotDict = {'nTicks': 5} # Have to include all filters in query, so that we check for all-band coverage. # Galaxy numbers calculated using 'bandpass' images only though. sqlconstraint = f'note not like "DD%"' metadata = f'{bandpass} band galaxies non-DD' metric = DepthLimitedNumGalMetric(m5Col=colmap['fiveSigmaDepth'], filterCol=colmap['filter'], nside=nside, filterBand=bandpass, redshiftBin='all', nfilters_needed=nfilters_needed, lim_mag_i_ptsrc=mag_cuts[maxYr], lim_ebv=lim_ebv) summary = [metrics.AreaSummaryMetric(area=18000, reduce_func=np.sum, decreasing=True, metricName='N Galaxies (18k)')] summary.append(metrics.SumMetric(metricName='N Galaxies (all)')) slicer = slicers.HealpixSlicer(nside=nside, useCache=False) bundle = mb.MetricBundle(metric, slicer, sqlconstraint, plotDict=plotDict, metadata=metadata, mapsList=[dustmap], displayDict=displayDict, summaryMetrics=summary, plotFuncs=subsetPlots) bundleList.append(bundle) ## WL metrics # Calculates the number of visits per pointing, after removing parts of the footprint due to dust/depth subgroupCount += 1 displayDict['subgroup'] = f'{subgroupCount}: WL' displayDict['order'] = 0 sqlconstraint = f'note not like "DD%" and filter = "{bandpass}"' metadata = f'{bandpass} band non-DD' minExpTime = 15 m = metrics.WeakLensingNvisits(m5Col=colmap['fiveSigmaDepth'], expTimeCol=colmap['exptime'], lsstFilter=bandpass, depthlim=mag_cuts[maxYr], ebvlim=lim_ebv, min_expTime=minExpTime) s = slicers.HealpixSlicer(nside=nside, useCache=False) displayDict['caption'] = f'The number of visits per pointing, over the same reduced footprint as ' displayDict['caption'] += f'described above. A cutoff of {minExpTime} removes very short visits.' displayDict['order'] = 1 bundle = mb.MetricBundle(m, s, sqlconstraint, mapsList=[dustmap], metadata=metadata, summaryMetrics=standardStats, displayDict=displayDict) bundleList.append(bundle) # This probably will get replaced by @pgris's SN metrics? subgroupCount += 1 displayDict['subgroup'] = f'{subgroupCount}: SNe Ia' displayDict['order'] = 0 # XXX-- use the light curves from PLASTICC here displayDict['caption'] = 'Fraction of normal SNe Ia (using PLaSTICCs)' sqlconstraint = 'note not like "DD%"' metadata = 'non-DD' 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, sqlconstraint, metadata=metadata, summaryMetrics=summary_stats, plotFuncs=plotFuncs, displayDict=displayDict) bundleList.append(bundle) subgroupCount += 1 displayDict['subgroup'] = f'{subgroupCount}: Camera Rotator' displayDict['caption'] = 'Kuiper statistic (0 is uniform, 1 is delta function) of the ' slicer = slicers.HealpixSlicer(nside=nside) metric1 = metrics.KuiperMetric('rotSkyPos') metric2 = metrics.KuiperMetric('rotTelPos') filterlist, colors, filterorders, filtersqls, filtermetadata = filterList(all=False, extraSql=None, extraMetadata=None) for f in filterlist: for m in [metric1, metric2]: plotDict = {'color': colors[f]} displayDict['order'] = filterorders[f] displayDict['caption'] += f"{m.colname} for visits in {f} band." bundleList.append(mb.MetricBundle(m, slicer, filtersqls[f], plotDict=plotDict, displayDict=displayDict, summaryMetrics=standardStats, plotFuncs=subsetPlots)) # Set the runName for all bundles and return the bundleDict. for b in bundleList: b.setRunName(runName) return mb.makeBundlesDictFromList(bundleList)