def getData(opsDb, sqlconstraint): # Define columns we want from opsim database (for metrics, slicers and stacker info). colnames = [ 'observationStartMJD', 'filter', 'fieldRA', 'fieldDec', 'observationStartLST', 'moonRA', 'moonDec', 'moonPhase', 'night' ] # Get data from database. simdata = opsDb.fetchMetricData(colnames, sqlconstraint) if len(simdata) == 0: raise Exception('No simdata found matching constraint %s' % (sqlconstraint)) # Hack because observationStartLst in HOURS here. :( simdata[ 'observationStartLST'] = simdata['observationStartLST'] / 24.0 * 360.0 # Add stacker columns. hourangleStacker = stackers.HourAngleStacker() simdata = hourangleStacker.run(simdata) filterStacker = stackers.FilterColorStacker() simdata = filterStacker.run(simdata) fieldIdStacker = stackers.OpSimFieldStacker() simdata = fieldIdStacker.run(simdata) # Fetch field data. #fields = opsDb.fetchFieldsFromFieldTable(degreesToRadians=True) fidx = np.unique(simdata['opsimFieldId'], return_index=True)[1] fields = np.recarray(len(fidx), dtype=[('opsimFieldId', np.float), ('fieldRA', np.float), ('fieldDec', np.float)]) fields['opsimFieldId'] = simdata['opsimFieldId'][fidx] fields['fieldRA'] = np.radians(simdata['fieldRA'][fidx]) fields['fieldDec'] = np.radians(simdata['fieldDec'][fidx]) return simdata, fields
def getData(opsDb, sqlconstraint): # Define columns we want from opsim database (for metrics, slicers and # stacker info). colnames = [ 'expMJD', 'filter', 'fieldID', 'fieldRA', 'fieldDec', 'lst', 'moonRA', 'moonDec', 'moonPhase', 'night' ] # Get data from database. simdata = opsDb.fetchMetricData(colnames, sqlconstraint) if len(simdata) == 0: raise Exception('No simdata found matching constraint %s' % (sqlconstraint)) # Add stacker columns. hourangleStacker = stackers.HourAngleStacker() simdata = hourangleStacker.run(simdata) # ZTF filterStacker = stackers.FilterColorStacker(filterMap={ 'g': 1, 'r': 2, 'i': 3 }) filterStacker.filter_rgb_map = { 'g': (0, 1, 0), # green 'r': (1, 0, 0), # red 'i': (1, 0, 1) } # red simdata = filterStacker.run(simdata) # Fetch field data. fields = opsDb.fetchFieldsFromFieldTable() return simdata, fields
def getData(opsDb, sqlconstraint): # Define columns we want from opsim database (for metrics, slicers and stacker info). colnames = ['observationStartMJD', 'filter', 'fieldId', 'fieldRA', 'fieldDec', 'observationStartLST', 'moonRA', 'moonDec', 'moonPhase', 'night'] # Get data from database. simdata = opsDb.fetchMetricData(colnames, sqlconstraint) if len(simdata) == 0: raise Exception('No simdata found matching constraint %s' %(sqlconstraint)) # Add stacker columns. hourangleStacker = stackers.HourAngleStacker() simdata = hourangleStacker.run(simdata) filterStacker = stackers.FilterColorStacker() simdata = filterStacker.run(simdata) # Fetch field data. fields = opsDb.fetchFieldsFromFieldTable(degreesToRadians=True) return simdata, fields
def testFilterColorStacker(self): """Test the filter color stacker.""" data = np.zeros(60, dtype=list(zip(['filter'], ['<U1']))) data['filter'][0:10] = 'u' data['filter'][10:20] = 'g' data['filter'][20:30] = 'r' data['filter'][30:40] = 'i' data['filter'][40:50] = 'z' data['filter'][50:60] = 'y' stacker = stackers.FilterColorStacker() data = stacker.run(data) # Check if re-run stacker raises warning (adding column twice). with warnings.catch_warnings(record=True) as w: warnings.simplefilter("always") data = stacker.run(data) assert len(w) > 1 assert "already present in simData" in str(w[-1].message) # Check if use non-recognized filter raises exception. data = np.zeros(600, dtype=list(zip(['filter'], ['<U1']))) data['filter'] = 'q' self.assertRaises(IndexError, stacker.run, data)
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))