Coverage for python/lsst/sims/catUtils/baseCatalogModels/OpSim3_61DBObject.py : 34%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1from builtins import zip
2from lsst.sims.catalogs.db import DBObject
3from lsst.sims.utils import ObservationMetaData
4from .BaseCatalogModels import BaseCatalogConfig
5from lsst.utils import getPackageDir
6from collections import OrderedDict
7import numpy
8import math
9import os
11from lsst.sims.utils import CircleBounds
13__all__ = ["OpSim3_61DBObject"]
16class OpSim3_61DBObject(DBObject):
17 """
18 This is a class which allows you to query the databse of OpSim runs (v 3_61)
19 """
20 config = BaseCatalogConfig()
21 config.load(os.path.join(getPackageDir("sims_catUtils"), "config", "db.py"))
22 host = config.host
23 port = config.port
24 database = config.database
25 driver = config.driver
27 #This is the table that this DBObject is querying
28 tableid = 'output_opsim3_61'
30 #: These are interpreted as SQL strings.
31 #They are passed to SpatialBounds objects
32 #and indicate the RA and Dec columns in degrees
33 raColName = 'fieldradeg'
34 decColName = 'fielddecdeg'
36 # columnNames maps column names as stored in the OpSim3_61 database
37 # to column names as they occur in the OpSim v3.3.5 summary table
38 columnNames = [('obsHistID','obshistid'),
39 ('SIM_SEED','expdate'),
40 ('pointingRA','fieldra'),
41 ('pointingDec','fielddec'),
42 ('moonRA','moonra'),
43 ('moonDec','moondec'),
44 ('rotSkyPos','rotskypos'),
45 ('rotTelPos','rottelpos'),
46 ('rawSeeing','rawseeing'),
47 ('sunAlt','sunalt'),
48 ('moonAlt','moonalt'),
49 ('dist2Moon','dist2moon'),
50 ('moonPhase','moonphase'),
51 ('expMJD','expmjd'),
52 ('airmass', 'airmass'),
53 ('filter', 'filter'),
54 ('visitExpTime', 'exptime-4.0', float)]
56 #columnTypes is a dict indicating the data types
57 #of the columns referred to in columnNames.
58 #columns not mentioned are floats
59 columnTypes ={'SIM_SEED':int,
60 'filter':(str,1),
61 'obsHistID':numpy.int64}
63 def __init__(self, driver=None, host=None, port=None, database=None):
64 super(OpSim3_61DBObject, self).__init__(driver=driver, host=host, port=port, database=database)
66 def getBasicQuery(self):
67 """
68 This class creates a string that is an SQL query of all the
69 columns needed to create an ObservationMetaData suitable for
70 generating a PhoSim input catalog. No constraints
71 are placed on the query (it will grab all entries in the database)
72 """
73 query = 'SELECT '
74 for name in self.columnNames:
75 if query != 'SELECT ':
76 query += ', '
77 query += name[1]
78 query += ' FROM ' + self.tableid
80 dtype=numpy.dtype([(name[0], self.columnTypes[name[0]]) if name[0] in self.columnTypes else (name[0], float) for name in self.columnNames])
82 return query, dtype
84 def executeConstrainedQuery(self, spatialBound, constraint=None):
85 """
86 This method will perform a query which is contrained on the sky by spatialBound.
87 You can add a supplementary constraint on another column using the 'contraint' kwarg.
89 param [in] spatialBound a SpatialBound object specifying the region of the sky from
90 which you want your pointings drawn
92 param [in] constraint an optional constraint on another column. Should be a string
93 of the form 'airmass=1.1'
95 param [out] a recarray of all of the pointings matching your constraints. This recarray
96 will contain all of the columns necessary for constructing an ObservationMetaData object
97 suitable for generating a PhoSim input catalog.
98 """
99 query, dtype = self.getBasicQuery()
100 query += ' WHERE '+spatialBound.to_SQL(self.raColName, self.decColName)
101 if constraint is not None:
102 query += ' and %s' % constraint
105 results = self.execute_arbitrary(query, dtype=dtype)
106 return results
108 def getObservationMetaData(self, searchCenter, searchRadius, constraint=None,
109 fovRadius=1.75, makeCircBounds=True, makeBoxBounds=False):
110 """
111 This method will perform a query on the OpSim3_61 for pointings within a given region
112 on the sky. It will then return a list of ObservationMetaData corresponding to the
113 OpSim pointings returned by that query.
115 param [in] searchCenter is a tuple (RA, Dec) indicating the center of the region
116 of the sky wherein to search for OpSim pointings (in degrees).
118 param [in] searchRadius is the radius of the region of the sky wherein to search
119 for OpSim pointings (in degrees).
121 param [in] constraint an optional constraint on another column. Should be a string
122 of the form 'airmass=1.1'
124 param [in] fovRadius is the radius (in degrees) of the resulting ObservationMetaDatas'
125 fields of view. If you have specified a box bounds this will be half the length of each
126 side of the box.
128 param [in] makeCircBounds a boolean telling this method to construct an ObservationMetaData
129 for a circular region of the sky centered on the specified OpSim pointing
131 param [in] make BoxBounds a boolean telling this method to construct an
132 ObservationMetaData for a square region of the sky centered on the specified
133 OpSim pointing
134 """
136 spatialBound = CircleBounds(numpy.radians(searchCenter[0]), numpy.radians(searchCenter[1]),
137 numpy.radians(searchRadius))
139 # get the results of the query as a numpy recarray
140 result = self.executeConstrainedQuery(spatialBound, constraint=constraint)
142 obs_list = []
143 ra_list = numpy.degrees(result['pointingRA'])
144 dec_list = numpy.degrees(result['pointingDec'])
145 rotSkyPos_list = numpy.degrees(result['rotSkyPos'])
146 for pointing, ra, dec, rotSkyPos in zip(result, ra_list, dec_list, rotSkyPos_list):
148 mjd = pointing['expMJD']
150 #because makeCircBounds defaults to True, check whether the user is
151 #requesting boxBounds before deciding to instantiate
152 #circBounds
154 boundType = None
155 boundLength = None
156 if makeBoxBounds:
157 boundType = 'box'
158 boundLength = numpy.array([fovRadius/math.cos(numpy.radians(dec)), fovRadius])
159 elif makeCircBounds:
160 boundType = 'circle'
161 boundLength = fovRadius
162 else:
163 raise ValueErr("Need either makeBoxBounds or makeCircBounds")
165 obs = ObservationMetaData(pointingRA=ra, pointingDec=dec,
166 rotSkyPos=rotSkyPos, mjd=mjd,
167 bandpassName=result['filter'][0],
168 boundType=boundType, boundLength=boundLength)
170 raw_opsim_dict = dict([(k, pointing[k]) for k in result.dtype.names])
171 obs.OpsimMetaData = raw_opsim_dict
172 obs_list.append(obs)
174 return obs_list