source: trunk/python/selector.py@ 2422

Last change on this file since 2422 was 2340, checked in by Malte Marquarding, 13 years ago

Ticket #256: make add return copy not reference

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