source: trunk/python/selector.py @ 1596

Last change on this file since 1596 was 1596, checked in by Malte Marquarding, 15 years ago

Return self or other in case of union with empty selector

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