Coverage for python/lsst/sims/survey/fields/field_selection.py : 22%

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
1try:
2 from itertools import zip_longest
3except ImportError:
4 from itertools import izip_longest as zip_longest
6__all__ = ["CUT_TYPEMAP", "FieldSelection"]
8CUT_TYPEMAP = {
9 "RA": "fieldRA",
10 "Dec": "fieldDec",
11 "GL": "fieldGL",
12 "GB": "fieldGB",
13 "EL": "fieldEL",
14 "EB": "fieldEB"
15}
16"""Mapping of short names to field database column names."""
18class FieldSelection(object):
19 """Class for constructing SQL queries on the survey fields database.
21 This class is for creating SQL queries to perform on the survey fields
22 database. It does not actually perform the queries.
23 """
25 def base_select(self):
26 """Return the base field query.
28 Returns
29 -------
30 str
31 """
32 return "select * from Field"
34 def combine_queries(self, *queries, **kwargs):
35 """Combine a set of queries.
37 Parameters
38 ----------
39 queries : str instances
40 A set of queries to join via the given operators.
41 combiners : tuple of str
42 A set of logical operations (and, or etc.) to join the queries
43 with. Defaults is an empty tuple. NOTE: A tuple with one logical
44 operator must look like ('and',).
45 order_by : str, optional
46 Set the order by clause. Default is fieldId.
48 Returns
49 -------
50 str:
51 The fully combined query.
52 """
53 combiners = kwargs.get("combiners", ())
54 if len(combiners) != len(queries) - 1:
55 raise RuntimeError("Number of combiners must be one less than "
56 "number of queries!")
58 order_by = kwargs.get("order_by", "fieldId")
60 final_query = []
61 final_query.append(self.base_select())
62 final_query.append("where")
63 for combine, query in zip_longest(combiners, queries):
64 final_query.append(query)
65 if combine is not None:
66 final_query.append(combine)
67 final_query.append("order by {}".format(order_by))
69 return self.finish_query(" ".join(final_query))
71 def finish_query(self, query):
72 """Put a semicolon at the end of a query.
74 Parameters
75 ----------
76 query : str
77 The SQL query to finish.
79 Returns
80 -------
81 str
82 The finished SQl query.
83 """
84 return query + ";"
86 def galactic_region(self, maxB, minB, endL, exclusion=False):
87 """Create a galactic region.
89 This function creates a sloping region around the galactic plane to
90 either include or exclude fields.
92 Parameters
93 ----------
94 maxB : float
95 The maximum galactic latitude at the galactic longitude of zero.
96 minB : float
97 The minimum galactic latitude at the galactic longitude of endL.
98 endL : float
99 The galactic longitude for the end of the envelope region.
100 exclusion : bool, optional
101 Flag to construct the query as an exclusion. Default is False.
103 Returns
104 -------
105 str
106 The appropriate query.
107 """
108 region_select = ">" if exclusion else "<="
109 band = maxB - minB
110 sql = '(abs(fieldGB) {0} ({1} - ({2} * '\
111 'abs(fieldGL)) / {3}))'.format(region_select, maxB, band, endL)
113 return sql
115 def get_all_fields(self):
116 """Return query for all fields.
118 Returns
119 -------
120 str
121 The query for all the fields.
122 """
123 return self.finish_query(self.base_select())
125 def select_region(self, region_type, start_value, end_value):
126 """Create a simple bounded region.
128 This function creates a bounded cut query based on the input values as
129 bounds for a given region. If start_value < end_value, the cut looks
130 like [start_value, end_value]. If start_value > end_value, the bounded
131 cut is or'd between the following cuts: [start_value, 360] and
132 [0, end_value].
134 Parameters
135 ----------
136 region_type : str
137 The name of the region to cut on.
138 start_value : float
139 The starting value (degrees) of the cut region.
140 end_value : float
141 The ending value (degrees) of the cut region.
143 Returns
144 -------
145 str
146 The appropriate query.
147 """
148 column_name = CUT_TYPEMAP[region_type]
149 if end_value > start_value:
150 sql = '{0} between {1} and {2}'.format(column_name, start_value,
151 end_value)
152 else:
153 sql = '({0} between {1} and 360 or '\
154 '{0} between 0 and {2})'.format(column_name, start_value,
155 end_value)
157 return sql
159 def select_user_regions(self, id_list):
160 """Create a query for a list of fields.of
162 This function creates a query focusing on field Ids. It is recommended
163 not to use this with more than a dozen Ids.
165 Parameters
166 ----------
167 id_list : list[int]
168 A set of field Ids to construct a query for.query
170 Returns
171 -------
172 str
173 The appropriate query.
174 """
175 sql = []
176 for fid in id_list:
177 sql.append("fieldId={}".format(fid))
178 sql.append("or")
180 # Don't need last or
181 del sql[-1]
183 return " ".join(sql)