def plotHist(bundleDicts, metricKey, runNames=None, **kwargs): ''' Plot histogram of evaluated metrics for each opsim in the bundleDicts on one figure. Args: bundleDicts(dict): A dictionary of bundleDict, keys are run names. metricKey(tuple): A tuple dictionary key for a specific metric, slicer and constraint combination. runNames(list): A list of opsim run names from which the metric values use to plot histogram are cacluated, default to None, meaning all opsims. ''' # init handler ph = plots.PlotHandler(savefig=False) # init plot healpixhist = plots.HealpixHistogram() # option to provide own plotDict for MAF if kwargs.get('plotDict') is not None: plotDictTemp = kwargs.get('plotDict') else: plotDictTemp = {'figsize': (8, 6), 'fontsize': 15, 'labelsize': 13} # check plotting key args if kwargs.get('logScale') is not None: plotDictTemp['logScale'] = kwargs.get('logScale') plotDicts = [] bundleList = [] # match keys metricKeys = key_match(bundleDicts, metricKey) # loop over all opsims if runNames is None: runNames = list(bundleDicts.keys()) # check if provided runName indeed exists elif not (set(runNames) <= set(bundleDicts.keys())): raise Exception("Provided runNames don't match the record!") for runName in runNames: plotDict = plotDictTemp.copy() plotDict.update({'label': runName}) plotDicts.append(plotDict) bundleList.append(bundleDicts[runName][metricKeys[runName]]) # set metrics to plot togehter ph.setMetricBundles(bundleList) fn = ph.plot(plotFunc=healpixhist, plotDicts=plotDicts) # set whether to draw hline vline = kwargs.get('axvline') if vline is not None: plt.figure(fn) plt.axvline(int(vline), color='k', ls='--')
def plotHist(bundleDicts, metricKey, runNames=None, ddf=False, **kwargs): ''' Plot histogram of evaluated metrics for each opsim in the bundleDicts on one figure. Args: bundleDicts(dict): A dictionary of bundleDict, keys are run names. metricKey(tuple): A tuple dictionary key for a specific metric, slicer and constraint combination. runNames(list): A list of opsim run names from which the metric values use to plot histogram are cacluated, default to None, meaning all opsims. ddf(bool): True if plotting for DDF, default is False. ''' # init handler ph = plots.PlotHandler(savefig=False) # init plot healpixhist = plots.HealpixHistogram() plotDictTemp = {'figsize': (8, 6), 'fontsize': 15, 'labelsize': 13} plotDicts = [] bundleList = [] # check if bins provided bins = kwargs.get('bins') if bins is not None: plotDictTemp['bins'] = int(bins) # loop over all opsims if runNames is None: runNames = list(bundleDicts.keys()) for runName in runNames: plotDict = plotDictTemp.copy() plotDict.update({'label': runName}) plotDicts.append(plotDict) # if plot for ddf, search for key if ddf: keys = [*bundleDicts[runName].keys()] metricKey = [elem for elem in keys if elem[1] == metricKey[1]][0] bundleList.append(bundleDicts[runName][metricKey]) # set metrics to plot togehter ph.setMetricBundles(bundleList) fn = ph.plot(plotFunc=healpixhist, plotDicts=plotDicts) # set whether to draw hline vline = kwargs.get('axvline') if vline is not None: plt.figure(fn) plt.axvline(int(vline), color='k', ls='--')
def calcCompleteness(orbitfile, obsfile, outDir): """ Calculate a basic set of metrics on the NEOs, including completeness. Saves the plots to disk. """ # Read data back from disk. mos = MoSlicer(orbitfile, Hrange=np.arange(13, 26, 0.5)) mos.readObs(obsfile) # Nobs metric = MoMetrics.NObsMetric() slicer = mos pandasConstraint = None plotDict = {'nxbins':100, 'nybins':100} nobs = mmb.MoMetricBundle(metric, slicer, pandasConstraint, runName=runName, metadata=metadata, plotDict=plotDict) # Calculate completeness. First we must calculate "DiscoveryChances". # Set up an example metric bundle. metric = MoMetrics.DiscoveryChancesMetric() slicer = mos pandasConstraint = None discovery = mmb.MoMetricBundle(metric, slicer, pandasConstraint, runName=runName, metadata=metadata, plotDict=plotDict) bdict = {'nobs':nobs, 'discovery':discovery} bg = mmb.MoMetricBundleGroup(bdict, outDir=outDir) bg.runAll() bg.plotAll() ph = plots.PlotHandler(outDir=outDir) # Then calculate 'completeness' as function of H, as a secondary metric. completeness = discovery.reduceMetric(discovery.metric.reduceFuncs['Completeness']) # And we can make an 'integrated over H distribution' version. completenessInt = completeness.reduceMetric(completeness.metric.reduceFuncs['CumulativeH']) Hmark = 21.0 for c in [completeness, completenessInt]: summaryMetric = ValueAtHMetric(Hmark=Hmark) c.setSummaryMetrics(summaryMetric) c.computeSummaryStats() label = "Completeness at H=%.1f: %.2f" %(Hmark, c.summaryValues['Value At H=%.1f' %Hmark]) c.setPlotDict({'label':label}) c.plot(plotFunc = moPlots.MetricVsH()) plt.axvline(Hmark, color='r', linestyle=':') plt.axhline(c.summaryValues['Value At H=%.1f' %(Hmark)], color='r', linestyle='-') plt.legend(loc=(0.9, 0.2)) plt.savefig(os.path.join(outDir, c.fileRoot + '_vsH' + '.png'), format='png')
def plot(self, plotHandler=None, plotFunc=None, outfileSuffix=None, savefig=False): """ Create all plots available from the slicer. plotHandler holds the output directory info, etc. Parameters ---------- plotHandler : Optional[PlotHandler] The plotHandler saves the output location and resultsDb connection for a set of plots. plotFunc : Optional[BasePlotter] Any plotter function. If not specified, the plotters in self.plotFuncs will be used. outfileSuffix : Optional[str] Optional string to append to the end of the plot output files. Useful when creating sequences of images for movies. savefig : Optional[bool] Flag indicating whether or not to save the figure to disk. Default is False. Returns ------- dict Dictionary of plotType:figure number key/value pairs, indicating what plots were created and what matplotlib figure numbers were used. """ # Generate a plotHandler if none was set. if plotHandler is None: plotHandler = plots.PlotHandler(savefig=savefig) # Make plots. if plotFunc is not None: if isinstance(plotFunc, plots.BasePlotter): plotFunc = plotFunc else: plotFunc = plotFunc() plotHandler.setMetricBundles([self]) plotHandler.setPlotDicts(plotDicts=[self.plotDict], reset=True) madePlots = {} if plotFunc is not None: fignum = plotHandler.plot(plotFunc, outfileSuffix=outfileSuffix) madePlots[plotFunc.plotType] = fignum else: for plotFunc in self.plotFuncs: fignum = plotHandler.plot(plotFunc, outfileSuffix=outfileSuffix) madePlots[plotFunc.plotType] = fignum return madePlots
def plotSky(bundleDicts, metricKey, **kwargs): ''' Plot healpix skymap for each opSim given a metric. One figure per opSim. Args: bundleDicts(dict): A dictionary of bundleDict, keys are run names. metricKey(tuple): A tuple dictionary key for a specific metric, slicer and constraint combination. ''' # init handler, plot, etc. ph = plots.PlotHandler(savefig=False) healpixSky = plots.HealpixSkyMap() metricKeys = key_match(bundleDicts, metricKey) # match keys # option to provide own plotDict for MAF if kwargs.get('plotDict') is not None: plotDict = kwargs.get('plotDict') else: plotDict = {} for run in bundleDicts: ph.setMetricBundles([bundleDicts[run][metricKeys[run]]]) ph.plot(plotFunc=healpixSky, plotDicts=plotDict)
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 plotMetricData(self, bundleDict, plotFunc, runlist=None, userPlotDict=None, layout=None, outDir=None, paramTitles=False, paramCols=None, savefig=False): if runlist is None: runlist = self.runlist if userPlotDict is None: userPlotDict = {} ph = plots.PlotHandler(outDir=outDir, savefig=savefig) bundleList = [] for r in runlist: bundleList.append(bundleDict[r]) ph.setMetricBundles(bundleList) plotDicts = [{} for r in runlist] # Depending on plotFunc, overplot or make many subplots. if plotFunc.plotType == 'SkyMap': # Note that we can only handle 9 subplots currently due # to how subplot identification (with string) is handled. if len(runlist) > 9: raise ValueError('Please try again with < 9 subplots for skymap.') # Many subplots. if 'colorMin' not in userPlotDict: colorMin = 100000000 for b in bundleDict: if 'zp' not in bundleDict[b].plotDict: tmp = bundleDict[b].metricValues.compressed().min() colorMin = min(tmp, colorMin) else: colorMin = bundleDict[b].plotDict['colorMin'] userPlotDict['colorMin'] = colorMin if 'colorMax' not in userPlotDict: colorMax = -100000000 for b in bundleDict: if 'zp' not in bundleDict[b].plotDict: tmp = bundleDict[b].metricValues.compressed().max() colorMax = max(tmp, colorMax) else: colorMax = bundleDict[b].plotDict['colorMax'] userPlotDict['colorMax'] = colorMax for i, pdict in enumerate(plotDicts): # Add user provided dictionary. pdict.update(userPlotDict) # Set subplot information. if layout is None: ncols = int(np.ceil(np.sqrt(len(runlist)))) nrows = int(np.ceil(len(runlist) / float(ncols))) else: ncols = layout[0] nrows = layout[1] pdict['subplot'] = int(str(nrows) + str(ncols) + str(i + 1)) if paramTitles is False: pdict['title'] = runlist[i] else: pdict['title'] = self._parameterTitles(runlist[i], paramCols=paramCols) # For the subplots we do not need the label pdict['label'] = '' if 'suptitle' not in userPlotDict: pdict['suptitle'] = ph._buildTitle() elif plotFunc.plotType == 'Histogram': # Put everything on one plot. if 'xMin' not in userPlotDict: xMin = 100000000 for b in bundleDict: if 'zp' not in bundleDict[b].plotDict: tmp = bundleDict[b].metricValues.compressed().min() xMin = min(tmp, xMin) else: xMin = bundleDict[b].plotDict['xMin'] userPlotDict['xMin'] = xMin if 'xMax' not in userPlotDict: xMax = -100000000 for b in bundleDict: if 'zp' not in bundleDict[b].plotDict: tmp = bundleDict[b].metricValues.compressed().max() xMax = max(tmp, xMax) else: xMax = bundleDict[b].plotDict['xMax'] userPlotDict['xMax'] = xMax for i, pdict in enumerate(plotDicts): pdict.update(userPlotDict) pdict['subplot'] = '111' # Legend and title will automatically be ok, I think. elif plotFunc.plotType == 'BinnedData': # Put everything on one plot. if 'yMin' not in userPlotDict: yMin = 100000000 for b in bundleDict: tmp = bundleDict[b].metricValues.compressed().min() yMin = min(tmp, yMin) userPlotDict['yMin'] = yMin if 'yMax' not in userPlotDict: yMax = -100000000 for b in bundleDict: tmp = bundleDict[b].metricValues.compressed().max() yMax = max(tmp, yMax) userPlotDict['yMax'] = yMax if 'xMin' not in userPlotDict: xMin = 100000000 for b in bundleDict: tmp = bundleDict[b].slicer.slicePoints['bins'].min() xMin = min(tmp, xMin) userPlotDict['xMin'] = xMin if 'xMax' not in userPlotDict: xMax = -100000000 for b in bundleDict: tmp = bundleDict[b].slicer.slicePoints['bins'].max() xMax = max(tmp, xMax) userPlotDict['xMax'] = xMax for i, pdict in enumerate(plotDicts): pdict.update(userPlotDict) pdict['subplot'] = '111' # Legend and title will automatically be ok, I think. if self.verbose: print(plotDicts) ph.plot(plotFunc, plotDicts=plotDicts)
def runSlices(opsimName, metadata, simdata, fields, bins, args, opsDb, verbose=False): # Set up the movie slicer. movieslicer = setupMovieSlicer(simdata, bins) # Set up formatting for output suffix. sliceformat = '%s0%dd' % ('%', int(np.log10(len(movieslicer))) + 1) # Get the telescope latitude info. lat_tele = Site(name='LSST').latitude_rad # Run through the movie slicer slicePoints and generate plots at each point. for i, ms in enumerate(movieslicer): t = time.time() slicenumber = sliceformat % (i) if verbose: print(slicenumber) # Set up metrics. if args.movieStepsize != 0: tstep = args.movieStepsize else: tstep = ms['slicePoint']['binRight'] - bins[i] if tstep > 1: tstep = 40. / 24. / 60. / 60. # Add simple view of time to plot label. times_from_start = ms['slicePoint']['binRight'] - (int(bins[0]) + 0.16 - 0.5) # Opsim years are 365 days (not 365.25) years = int(times_from_start / 365) days = times_from_start - years * 365 plotlabel = 'Year %d Day %.4f' % (years, days) # Set up metrics. metricList, plotDictList = setupMetrics( opsimName, metadata, plotlabel=plotlabel, t0=ms['slicePoint']['binRight'], tStep=tstep, years=years, verbose=verbose) # Identify the subset of simdata in the movieslicer 'data slice' simdatasubset = simdata[ms['idxs']] # Set up opsim slicer on subset of simdata provided by movieslicer opslicer = slicers.OpsimFieldSlicer( simDataFieldIdColName='opsimFieldId', fieldIdColName='opsimFieldId') # Set up metricBundles to combine metrics, plotdicts and slicer. bundles = [] sqlconstraint = '' for metric, plotDict in zip(metricList, plotDictList): bundles.append( metricBundles.MetricBundle(metric, opslicer, constraint=sqlconstraint, metadata=metadata, runName=opsimName, plotDict=plotDict)) # Remove (default) stackers from bundles, because we've already run them above on the original data. for mb in bundles: mb.stackerList = [] bundledict = metricBundles.makeBundlesDictFromList(bundles) # Set up metricBundleGroup to handle metrics calculation + plotting bg = metricBundles.MetricBundleGroup(bundledict, opsDb, outDir=args.outDir, resultsDb=None, saveEarly=False) # 'Hack' bundleGroup to just go ahead and run the metrics, without querying the database. simData = simdatasubset bg.fieldData = fields bg.setCurrent(sqlconstraint) bg.runCurrent(constraint=sqlconstraint, simData=simData) # Plot data each metric, for this slice of the movie, adding slicenumber as a suffix for output plots. # Plotting here, rather than automatically via sliceMetric method because we're going to rotate the sky, # and add extra legend info and figure text (for FilterColors metric). ph = plots.PlotHandler(outDir=args.outDir, figformat='png', dpi=72, thumbnail=False, savefig=False) obsnow = np.where(simdatasubset['observationStartMJD'] == simdatasubset['observationStartMJD'].max())[0] raCen = np.radians( np.mean(simdatasubset[obsnow]['observationStartLST'])) # Calculate horizon location. horizonlon, horizonlat = addHorizon(lat_telescope=lat_tele) # Create the plot for each metric and save it (after some additional manipulation). for mb in bundles: ph.setMetricBundles([mb]) fignum = ph.plot(plotFunc=plots.BaseSkyMap(), plotDicts={'raCen': raCen}) fig = plt.figure(fignum) ax = plt.gca() # Add horizon and zenith. plt.plot(horizonlon, horizonlat, 'k.', alpha=0.3, markersize=1.8) plt.plot(0, lat_tele, 'k+') # For the FilterColors metric, add some extra items. if mb.metric.name == 'FilterColors': # Add the time stamp info (plotlabel) with a fancybox. plt.figtext(0.75, 0.9, '%s' % (plotlabel), bbox=dict(boxstyle='Round, pad=0.7', fc='w', ec='k', alpha=0.5)) # Add a legend for the filters. filterstacker = stackers.FilterColorStacker() for i, f in enumerate(['u', 'g', 'r', 'i', 'z', 'y']): plt.figtext(0.92, 0.55 - i * 0.035, f, color=filterstacker.filter_rgb_map[f]) # Add a moon. moonRA = np.radians(np.mean(simdatasubset[obsnow]['moonRA'])) lon = -(moonRA - raCen - np.pi) % (np.pi * 2) - np.pi moonDec = np.radians(np.mean(simdatasubset[obsnow]['moonDec'])) # Note that moonphase is 0-100 (translate to 0-1). 0=new. moonPhase = np.mean(simdatasubset[obsnow]['moonPhase']) / 100. alpha = np.max([moonPhase, 0.15]) circle = Circle((lon, moonDec), radius=0.05, color='k', alpha=alpha) ax.add_patch(circle) # Add some explanatory text. ecliptic = Line2D([], [], color='r', label="Ecliptic plane") galaxy = Line2D([], [], color='b', label="Galactic plane") horizon = Line2D([], [], color='k', alpha=0.3, label="20 deg elevation limit") moon = Line2D([], [], color='k', linestyle='', marker='o', markersize=8, alpha=alpha, label="\nMoon (Dark=Full)\n (Light=New)") zenith = Line2D([], [], color='k', linestyle='', marker='+', markersize=5, label="Zenith") plt.legend( handles=[horizon, zenith, galaxy, ecliptic, moon], loc=[0.1, -0.35], ncol=3, frameon=False, title= 'Aitoff plot showing HA/Dec of simulated survey pointings', numpoints=1, fontsize='small') # Save figure. plt.savefig(os.path.join( args.outDir, mb.metric.name + '_' + slicenumber + '_SkyMap.png'), format='png', dpi=72) plt.close('all') dt, t = dtime(t) if verbose: print('Ran and plotted slice %s of movieslicer in %f s' % (slicenumber, dt))
sql = 'filter="%s"' % filterName sql += ' and '+wfdWhere sql += nw plotDict = {'label':'Config %s, year %i' % (raftConfig, year), 'legendloc':'lower right'} bundle = metricBundles.MetricBundle(metric,slicer,sql, summaryMetrics=summaryStats, plotDict=plotDict) bundle.year = year bundle.filterName = filterName bundle.config = raftConfig bundleList.append(bundle) bg = metricBundles.makeBundlesDictFromList(bundleList) group = metricBundles.MetricBundleGroup(bg, opsdb, outDir=outDir, resultsDb=resultsDb) group.runAll() group.plotAll() #group.readAll() ph = plots.PlotHandler(outDir=outDir, resultsDb=resultsDb) for year in years: for filterName in filters: bl = [] for bundle in bundleList: if (bundle.year == year) & (bundle.filterName == filterName): bl.append(bundle) ph.setMetricBundles(bl) ph.plot(plotFunc=plots.HealpixPowerSpectrum())