source: trunk/python/selector.py@ 2870

Last change on this file since 2870 was 2870, checked in by Takeshi Nakazato, 11 years ago

New Development: No

JIRA Issue: Yes CAS-5858

Ready for Test: Yes

Interface Changes: Yes

What Interface Changed: Added selector.set_msselection_field method

Test Programs: none

Put in Release Notes: No

Module(s): sd

Description: Describe your changes here...

Added selector.set_msselection_field to support multi-field selection
based on msselection syntax.


File size: 9.7 KB
RevLine 
[1875]1import re
[2870]2import string
[1875]3from asap._asap import selector as _selector, srctype
[1826]4from asap.utils import unique, _to_list
[948]5
[932]6class selector(_selector):
[948]7 """
8 A selection object to be applied to scantables to restrict the
9 scantables to specific rows.
10 """
[1930]11 fields = ["pols", "ifs", "beams", "scans", "cycles", "name", "query", "types", "rows"]
[932]12
[1576]13 def __init__(self, *args, **kw):
14 if len(args) == 1:
15 if isinstance(args[0], self.__class__) \
16 or isinstance(args[0], _selector):
17 _selector.__init__(self, args[0])
18 else:
19 raise TypeError("Argument can only be a selector object")
20 else:
21 _selector.__init__(self)
22 for k,v in kw.items():
23 if k in self.fields:
24 func = getattr(self, "set_%s" % k)
25 func(v)
26
[932]27 def reset(self):
28 """
29 Unset all selections.
30 """
31 self._reset()
32
[948]33 def is_empty(self):
34 """
35 Has anything been set?
36 """
37 return self._empty()
38
[932]39 def set_polarisations(self, pols=[]):
40 """
41 Set the polarisations to be selected in the scantable.
42 Parameters:
43 pols: a list of integers of 0-3, or strings, e.g ["I","Q"].
44 Default [] is no selection
45 Example:
46 sel = selector()
47 # These are equivalent if data is 'linear'
48 sel.set_polarisations(["XX","Re(XY)"])
49 sel.set_polarisations([0,2])
50 # reset the polarisation selection
51 sel.set_polarisations()
[948]52
[932]53 """
[954]54 vec = _to_list(pols, str) or _to_list(pols, int)
[1045]55 if isinstance(vec, list): # is an empty and/or valid vector
[932]56 if len(vec) and isinstance(vec[-1],str):
[954]57 self._setpolstrings(vec)
[932]58 return
59 self._setpols(vec)
60 else:
61 raise TypeError('Unknown pol type. Please use [0,1...] or ["XX","YY"...]')
[1576]62
[1349]63 # for the americans
[1542]64 set_polarizations = set_polarisations
65 # for the lazy
66 set_pols = set_polarisations
[932]67
68 def set_ifs(self, ifs=[]):
69 """
70 Set a sequence of IF numbers (0-based).
71 Parameters:
72 ifs: a list of integers. Default [] is to unset the selection.
73 """
74 vec = _to_list(ifs, int)
[1045]75 if isinstance(vec,list):
[932]76 self._setifs(vec)
77 else:
78 raise TypeError('Unknown IFno type. Use lists of integers.')
79
80 def set_scans(self, scans=[]):
81 """
82 Set a sequence of Scan numbers (0-based).
83 Parameters:
84 scans: a list of integers. Default [] is to unset the selection.
85 """
86 vec = _to_list(scans, int)
[1045]87 if isinstance(vec,list):
[932]88 self._setscans(vec)
89 else:
90 raise TypeError('Unknown Scan number type. Use lists of integers.')
91
92 def set_beams(self, beams=[]):
93 """
94 Set a sequence of Beam numbers (0-based).
95 Parameters:
96 beams: a list of integers. Default [] is to unset the selection.
97 """
98 vec = _to_list(beams, int)
[1045]99 if isinstance(vec,list):
[932]100 self._setbeams(vec)
101 else:
102 raise TypeError('Unknown Beam number type. Use lists of integers.')
103
104 def set_cycles(self, cycles=[]):
105 """
106 Set a sequence of IF numbers (0-based).
107 Parameters:
108 cycless: a list of integers. Default [] is to unset the selection.
109 """
110 vec = _to_list(cycles, int)
[1045]111 if isinstance(vec,list):
[932]112 self._setcycles(vec)
113 else:
114 raise TypeError('Unknown Cycle number type. Use lists of integers.')
115
[948]116
[932]117 def set_name(self, name):
118 """
119 Set a selection based on a name. This can be a unix pattern , e.g. "*_R"
120 Parameters:
121 name: a string containing a source name or pattern
122 Examples:
123 # select all reference scans which start with "Orion"
124 selection.set_name("Orion*_R")
125 """
126 if isinstance(name, str):
[952]127 self._setname(name)
[932]128 else:
129 raise TypeError('name must be a string')
[948]130
[932]131 def set_tsys(self, tsysmin=0.0, tsysmax=None):
132 """
133 Select by Tsys range.
134 Parameters:
135 tsysmin: the lower threshold. Default 0.0
136 tsysmax: the upper threshold. Default None.
137 Examples:
138 # select all spectra with Tsys <= 500.0
139 selection.set_tsys(tsysmax=500.0)
[948]140
[932]141 """
[963]142 taql = "SELECT FROM $1 WHERE TSYS[0] >= %f" % (tsysmin)
[932]143 if isinstance(tsysmax, float):
[963]144 taql = taql + " AND TSYS[0] <= %f" % ( tsysmax)
[932]145 self._settaql(taql)
146
147 def set_query(self, query):
148 """
149 Select by Column query. Power users only!
150 Example:
151 # select all off scans with integration times over 60 seconds.
[1875]152 selection.set_query("SRCTYPE == PSOFF AND INTERVAL > 60.0")
[932]153 """
[1875]154 rx = re.compile("((SRCTYPE *[!=][=] *)([a-zA-Z.]+))", re.I)
155 for r in rx.findall(query):
156 sval = None
157 stype = r[-1].lower()
158 if stype.find('srctype.') == -1:
159 stype = ".".join(["srctype", stype])
160 try:
161 sval = eval(stype)
162 sval = "%s%d" % (r[1], sval)
163 except:
164 continue
165 query = query.replace(r[0], sval)
[932]166 taql = "SELECT FROM $1 WHERE " + query
167 self._settaql(taql)
[948]168
169 def set_order(self, order):
170 """
171 Set the order the scantable should be sorted by.
172 Parameters:
[1045]173 order: The list of column names to sort by in order
[948]174 """
175 self._setorder(order)
176
[1819]177 def set_rows(self, rows=[]):
178 """
179 Set a sequence of row numbers (0-based). Power users Only!
180 NOTICE row numbers can be changed easily by sorting,
[1826]181 prior selection, etc.
[1819]182 Parameters:
183 rows: a list of integers. Default [] is to unset the selection.
184 """
[1826]185 vec = _to_list(rows, int)
[1819]186 if isinstance(vec,list):
187 self._setrows(vec)
188 else:
189 raise TypeError('Unknown row number type. Use lists of integers.')
190
191 def set_types(self, types=[]):
192 """
[1826]193 Set a sequence of source types.
[1819]194 Parameters:
195 types: a list of integers. Default [] is to unset the selection.
196 """
[1826]197 vec = _to_list(types, int)
[1819]198 if isinstance(vec,list):
199 self._settypes(vec)
200 else:
201 raise TypeError('Unknown row number type. Use lists of integers.')
202
[2870]203 def set_msselection_field(self, selection):
204 """
205 """
206 selection_list = map(string.strip, selection.split(','))
207 query_list = list(self.generate_query(selection_list))
208 query = 'SELECT FROM $1 WHERE ' + ' || '.join(query_list)
209 self._settaql(query)
210
211 def generate_query(self, selection_list):
212 for s in selection_list:
213 if re.match('.*\*.*', s):
214 #print '"%s" is pattern match using *'%(s)
215 yield 'SRCNAME == pattern(\'%s\')'%(s)
216 elif re.match('^<=?[0-9]*$', s):
217 #print '"%s" is ID selection using < or <='%(s)
218 elif re.match('^>=?[0-9]*$', s):
219 #print '"%s" is ID selection using > or >='%(s)
220 elif re.match('^[0-9]+~[0-9]+$', s):
221 #print '"%s" is ID selection using ~'%(s)
222 else:
223 #print '"%s" is exact match'%(s)
224 yield 'SRCNAME == pattern(\'%s\')'%(s)
225
[948]226 def get_scans(self):
227 return list(self._getscans())
228 def get_cycles(self):
229 return list(self._getcycles())
230 def get_beams(self):
231 return list(self._getbeams())
232 def get_ifs(self):
233 return list(self._getifs())
234 def get_pols(self):
235 return list(self._getpols())
236 def get_poltypes(self):
237 return list(self._getpoltypes())
238 def get_order(self):
239 return list(self._getorder())
[1819]240 def get_types(self):
241 return list(self._gettypes())
[1930]242 def get_rows(self):
243 return list(self._getrows())
[1337]244 def get_query(self):
245 prefix = "SELECT FROM $1 WHERE "
246 return self._gettaql().replace(prefix, "")
[1542]247
[948]248 def get_name(self):
249 print "NYI"
250 s = self._gettaql()
[1337]251 return
252 def __str__(self):
253 out = ""
254 d = {"SCANNO": self.get_scans(),
255 "CYCLENO": self.get_cycles(),
256 "BEAMNO": self.get_beams(),
257 "IFNO": self.get_ifs(),
258 "Pol Type": self.get_poltypes(),
259 "POLNO": self.get_pols(),
260 "QUERY": self.get_query(),
[1930]261 "SRCTYPE": self.get_types(),
262 "ROWS": self.get_rows(),
[1337]263 "Sort Order": self.get_order()
264 }
265 for k,v in d.iteritems():
266 if v:
267 out += "%s: %s\n" % (k, v)
268 if len(out):
269 return out[:-1]
270 else:
271 return out
[2340]272
[948]273 def __add__(self, other):
274 """
275 Merge two selections.
276 """
[1596]277 if self.is_empty():
[2340]278 return selector(other)
[1596]279 elif other.is_empty():
[2340]280 return selector(self)
[948]281 union = selector()
282 gets = [[self._getscans(), other._getscans(), union._setscans],
283 [self._getcycles(), other._getcycles(),union._setcycles],
284 [self._getbeams(), other._getbeams(), union._setbeams],
285 [self._getifs(), other._getifs(), union._setifs],
286 [self._getpols(), other._getpols(), union._setpols]]
287 for v in gets:
288 vec = list(v[0]+v[1])
289 vec.sort()
290 v[2](unique(vec))
[1349]291 q = other.get_query()
292 qs = self.get_query()
293 if len(q) and len(qs):
294 union.set_query(qs +" AND " + q)
295 else:
296 if len(q):
297 union.set_query(q)
298 elif len(qs):
299 union.set_query(qs)
[948]300 return union
Note: See TracBrowser for help on using the repository browser.