Changeset 2013 for trunk


Ignore:
Timestamp:
02/25/11 20:33:21 (14 years ago)
Author:
Kana Sugimoto
Message:

New Development: Yes

JIRA Issue: Yes (CAS-1425)

Ready for Test: Yes

Interface Changes: Yes

What Interface Changed: Two new methods are added to scantable class, i.e., parse_maskexpr and _parse_selection.

Test Programs:

scan=asap.scantable('FILENAME')
scan.parse_maskexpr('<2:-58~1100,2~13:<1200.;>9000.,15')

Put in Release Notes: No

Module(s): scantable

Description:

Added a new public method scantable.parse_maskexpr and an internal method
scantable._parse_selection. scantable..parse_maskexpr parses a CASA type channel
selection syntax string and returns a dictionary of valid IF (key) and masklist
combinations. See help for more details


File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/python/scantable.py

    r2012 r2013  
    12711271                break
    12721272        return istart,iend
     1273
     1274    @asaplog_post_dec
     1275    def parse_maskexpr(self,maskstring):
     1276        """
     1277        Parse CASA type mask selection syntax (IF dependent).
     1278
     1279        Parameters:
     1280            maskstring : A string mask selection expression.
     1281                         A comma separated selections mean different IF -
     1282                         channel combinations. IFs and channel selections
     1283                         are partitioned by a colon, ':'.
     1284                     examples:
     1285                         '<2,4~6,9'  = IFs 0,1,4,5,6,9 (all channels)
     1286                         '3:3~45;60' = channels 3 to 45 and 60 in IF 3
     1287                         '0~1:2~6,8' = channels 2 to 6 in IFs 0,1, and
     1288                                       all channels in IF8
     1289        Returns:
     1290        A dictionary of selected (valid) IF and masklist pairs,
     1291        e.g. {'0': [[50,250],[350,462]], '2': [[100,400],[550,974]]}
     1292        """
     1293        if not isinstance(maskstring,str):
     1294            asaplog.post()
     1295            asaplog.push("Invalid mask expression")
     1296            asaplog.post("ERROR")
     1297       
     1298        valid_ifs = self.getifnos()
     1299        frequnit = self.get_unit()
     1300        seldict = {}
     1301        ## split each selection
     1302        sellist = maskstring.split(',')
     1303        for currselstr in sellist:
     1304            selset = currselstr.split(':')
     1305            # spw and mask string (may include ~, < or >)
     1306            spwmasklist = self._parse_selection(selset[0],typestr='integer',
     1307                                               offset=1,minval=min(valid_ifs),
     1308                                               maxval=max(valid_ifs))
     1309            for spwlist in spwmasklist:
     1310                selspws = []
     1311                for ispw in range(spwlist[0],spwlist[1]+1):
     1312                    # Put into the list only if ispw exists
     1313                    if valid_ifs.count(ispw):
     1314                        selspws.append(ispw)
     1315            del spwmasklist, spwlist
     1316
     1317            # parse frequency mask list
     1318            if len(selset) > 1:
     1319                freqmasklist = self._parse_selection(selset[1],typestr='float',
     1320                                                    offset=0.)
     1321            else:
     1322                # want to select the whole spectrum
     1323                freqmasklist = [None]
     1324
     1325            ## define a dictionary of spw - masklist combination
     1326            for ispw in selspws:
     1327                #print "working on", ispw
     1328                spwstr = str(ispw)
     1329                if len(selspws) == 0:
     1330                    # empty spw
     1331                    continue
     1332                else:
     1333                    ## want to get min and max of the spw and
     1334                    ## offset to set for '<' and '>'
     1335                    if frequnit == 'channel':
     1336                        minfreq = 0
     1337                        maxfreq = self.nchan(ifno=ispw)
     1338                        offset = 0.5
     1339                    else:
     1340                        ## This is ugly part. need improvement
     1341                        for ifrow in xrange(self.nrow()):
     1342                            if self.getif(ifrow) == ispw:
     1343                                #print "IF",ispw,"found in row =",ifrow
     1344                                break
     1345                        freqcoord = self.get_coordinate(ifrow)
     1346                        freqs = self._getabcissa(ifrow)
     1347                        minfreq = min(freqs)
     1348                        maxfreq = max(freqs)
     1349                        if len(freqs) == 1:
     1350                            offset = 0.5
     1351                        elif frequnit.find('Hz') > 0:
     1352                            offset = abs(freqcoord.to_frequency(1,unit=frequnit)
     1353                                      -freqcoord.to_frequency(0,unit=frequnit))*0.5
     1354                        elif frequnit.find('m/s') > 0:
     1355                            offset = abs(freqcoord.to_velocity(1,unit=frequnit)
     1356                                      -freqcoord.to_velocity(0,unit=frequnit))*0.5
     1357                        else:
     1358                            asaplog.post()
     1359                            asaplog.push("Invalid frequency unit")
     1360                            asaplog.post("ERROR")
     1361                        del freqs, freqcoord, ifrow
     1362                    for freq in freqmasklist:
     1363                        selmask = freq or [minfreq, maxfreq]
     1364                        if selmask[0] == None:
     1365                            ## selection was "<freq[1]".
     1366                            if selmask[1] < minfreq:
     1367                                ## avoid adding region selection
     1368                                selmask = None
     1369                            else:
     1370                                selmask = [minfreq,selmask[1]-offset]
     1371                        elif selmask[1] == None:
     1372                            ## selection was ">freq[0]"
     1373                            if selmask[0] > maxfreq:
     1374                                ## avoid adding region selection
     1375                                selmask = None
     1376                            else:
     1377                                selmask = [selmask[0]+offset,maxfreq]
     1378                        if selmask:
     1379                            if not seldict.has_key(spwstr):
     1380                                # new spw selection
     1381                                seldict[spwstr] = []
     1382                            seldict[spwstr] += [selmask]
     1383                    del minfreq,maxfreq,offset,freq,selmask
     1384                del spwstr
     1385            del freqmasklist
     1386        del valid_ifs
     1387        if len(seldict) == 0:
     1388            asaplog.post()
     1389            asaplog.push("No valid selection in the mask expression: "+maskstring)
     1390            asaplog.post("WARN")
     1391            return None
     1392        msg = "Selected masklist:\n"
     1393        for sif, lmask in seldict.iteritems():
     1394            msg += "   IF"+sif+" - "+str(lmask)+"\n"
     1395        asaplog.push(msg)
     1396        return seldict
     1397
     1398    def _parse_selection(self,selstr,typestr='float',offset=0.,minval=None,maxval=None):
     1399        """
     1400        Parameters:
     1401            selstr :    The Selection string, e.g., '<3;5~7;100~103;9'
     1402            typestr :   The type of the values in returned list
     1403                        ('integer' or 'float')
     1404            offset :    The offset value to subtract from or add to
     1405                        the boundary value if the selection string
     1406                        includes '<' or '>'
     1407            minval, maxval :  The minimum/maximum values to set if the
     1408                              selection string includes '<' or '>'.
     1409                              The list element is filled with None by default.
     1410        Returns:
     1411            A list of min/max pair of selections.
     1412        Example:
     1413            _parseSelection('<3;5~7;9',typestr='int',offset=1,minval=0)
     1414            returns [[0,2],[5,7],[9,9]]
     1415        """
     1416        selgroups = selstr.split(';')
     1417        sellists = []
     1418        if typestr.lower().startswith('int'):
     1419            formatfunc = int
     1420        else:
     1421            formatfunc = float
     1422       
     1423        for currsel in  selgroups:
     1424            if currsel.find('~') > 0:
     1425                minsel = formatfunc(currsel.split('~')[0].strip())
     1426                maxsel = formatfunc(currsel.split('~')[1].strip())
     1427            elif currsel.strip().startswith('<'):
     1428                minsel = minval
     1429                maxsel = formatfunc(currsel.split('<')[1].strip()) \
     1430                         - formatfunc(offset)
     1431            elif currsel.strip().startswith('>'):
     1432                minsel = formatfunc(currsel.split('>')[1].strip()) \
     1433                         + formatfunc(offset)
     1434                maxsel = maxval
     1435            else:
     1436                minsel = formatfunc(currsel)
     1437                maxsel = formatfunc(currsel)
     1438            sellists.append([minsel,maxsel])
     1439        return sellists
    12731440
    12741441#    def get_restfreqs(self):
Note: See TracChangeset for help on using the changeset viewer.