Ignore:
Timestamp:
05/18/11 12:48:33 (13 years ago)
Author:
Kana Sugimoto
Message:

New Development: No

JIRA Issue: Yes (CAS-2963/ATNF-240)

Ready for Test: Yes

Interface Changes: No

What Interface Changed:

Test Programs: comare statistic result of interactive operation with command line none

Put in Release Notes: No

Module(s): asapplotter, sdplot

Description:

statistic mode in ASAP plotter now prints statistics (max, min, median, mean, sum, std dev) of
spectra only in the selected subplot.


File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/python/customgui_base.py

    r2171 r2172  
    66from asap import scantable
    77from asap._asap import stmath
     8from asap.utils import _n_bools, mask_not, mask_or
    89
    910######################################
     
    113114
    114115
    115     ### Calculate statistics of the selected area.
    116     def _single_mask(self,event):
    117         # Do not fire event when in zooming/panning mode
    118         if not self.figmgr.toolbar.mode == '':
    119             return
    120         # When selected point is out of panels
    121         if event.inaxes == None:
    122             return
    123         if event.button == 1:
    124             baseinv=True
    125         elif event.button == 3:
    126             baseinv=False
    127         else:
    128             return
    129 
    130         def _calc_stats():
    131             msk=mymask.get_mask()
    132             statstr = ['max', 'min', 'mean', 'median', 'sum', 'stddev', 'rms']
    133             for stat in statstr:
    134                 mymask.scan.stats(stat=stat,mask=msk)
    135 
    136         # Interactive mask definition
    137         from asap.interactivemask import interactivemask
    138         mymask = interactivemask(plotter=self.plotter,scan=self.plotter._data)
    139         # Create initial mask
    140         mymask.set_basemask(invert=baseinv)
    141         # Inherit event
    142         mymask.set_startevent(event)
    143         # Set callback func
    144         mymask.set_callback(_calc_stats)
    145         # Selected mask
    146         mymask.select_mask(once=True,showmask=False)
    147 
     116    ### Notation
    148117    def _mod_note(self,event):
    149118        # Do not fire event when in zooming/panning mode
     
    167136        #print "No text picked"
    168137        return False
     138
     139
     140    ### Purely plotter based statistics calculation of a selected area.
     141    ### No access to scantable
     142    def _single_mask(self,event):
     143        # Do not fire event when in zooming/panning mode
     144        if not self.figmgr.toolbar.mode == '':
     145            return
     146        # When selected point is out of panels
     147        if event.inaxes == None:
     148            return
     149        if event.button == 1:
     150            exclude=False
     151        elif event.button == 3:
     152            exclude=True
     153        else:
     154            return
     155
     156        self._thisregion = {'axes': event.inaxes,'xs': event.x,
     157                            'worldx': [event.xdata,event.xdata],
     158                            'invert': exclude}
     159        self.xold = event.x
     160        self.xdataold = event.xdata
     161
     162        self.plotter._plotter.register('button_press',None)
     163        self.plotter._plotter.register('motion_notify', self._xspan_draw)
     164        self.plotter._plotter.register('button_press', self._xspan_end)
     165
     166    def _xspan_draw(self,event):
     167        if event.inaxes == self._thisregion['axes']:
     168            xnow = event.x
     169            self.xold = xnow
     170            self.xdataold = event.xdata
     171        else:
     172            xnow = self.xold
     173        try: self.lastspan
     174        except AttributeError: pass
     175        else:
     176            if self.lastspan: self._remove_span(self.lastspan)
     177
     178        self.lastspan = self._draw_span(self._thisregion['axes'],self._thisregion['xs'],xnow,fill="")
     179        del xnow
     180
     181    def _draw_span(self,axes,x0,x1,**kwargs):
     182        pass
     183
     184    def _remove_span(self,span):
     185        pass
     186
     187    @asaplog_post_dec
     188    def _xspan_end(self,event):
     189        if not self.figmgr.toolbar.mode == '':
     190            return
     191        #if event.button != 1:
     192        #    return
     193
     194        try: self.lastspan
     195        except AttributeError: pass
     196        else:
     197            self._remove_span(self.lastspan)
     198            del self.lastspan
     199        if event.inaxes == self._thisregion['axes']:
     200            xdataend = event.xdata
     201        else:
     202            xdataend = self.xdataold
     203
     204        self._thisregion['worldx'][1] = xdataend
     205        # print statistics of spectra in subplot
     206        self._subplot_stats(self._thisregion)
     207       
     208        # release event
     209        self.plotter._plotter.register('button_press',None)
     210        self.plotter._plotter.register('motion_notify',None)
     211        # Clear up region selection
     212        self._thisregion = None
     213        self.xdataold = None
     214        self.xold = None
     215        # finally recover region selection event
     216        self.plotter._plotter.register('button_press',self._single_mask)
     217
     218    def _subplot_stats(self,selection):
     219        #from numpy import ma, ndarray
     220        import numpy
     221        statstr = ['max', 'min', 'median', 'mean', 'sum', 'std'] #'rms']
     222        panelstr = selection['axes'].title.get_text()
     223        ssep = "-"*70
     224        asaplog.push(ssep)
     225        asaplog.post()
     226        for line in selection['axes'].lines:
     227            label = panelstr + ", "+line.get_label()
     228            x = line.get_xdata()
     229            selmsk = self._create_flag_from_array(x,selection['worldx'],selection['invert'])
     230            y = line.get_ydata()
     231            if isinstance(y,numpy.ma.masked_array):
     232                ydat = y.data
     233                basemsk = y.mask
     234            else:
     235                ydat = y
     236                basemsk = False
     237            if not isinstance(basemsk, bool):
     238                # should be ndarray
     239                newmsk = mask_or(selmsk,basemsk)
     240            elif basemsk:
     241                # the whole original spectrum is flagged
     242                newmsk = basemsk
     243            else:
     244                # no channel was flagged originally
     245                newmsk = selmsk
     246            mdata = numpy.ma.masked_array(ydat,mask=newmsk)
     247            del x, y, ydat, basemsk, selmsk, newmsk
     248            statval = {}
     249            for stat in statstr:
     250                statval[stat] = getattr(numpy,stat)(mdata)
     251            self._print_stats(statval,statstr=statstr,label=label,\
     252                              mask=selection['worldx'],\
     253                              unmask=selection['invert'])
     254            asaplog.push(ssep)
     255            asaplog.post()
     256            del mdata, statval
     257        del ssep, panelstr
     258
     259    def _create_flag_from_array(self,x,masklist,invert):
     260        # Return True for channels which should be EXCLUDED (flag)
     261        if len(masklist) <= 1:
     262            asaplog.push()
     263            asaplog.post("masklist should be a list of 2 elements")
     264            asaplog.push("ERROR")
     265        n = len(x)
     266        # Base mask: flag out all channels
     267        mask = _n_bools(n, True)
     268        minval = min(masklist[0:2])
     269        maxval = max(masklist[0:2])
     270        for i in range(n):
     271            if minval <= x[i] <= maxval:
     272                mask[i] = False
     273        if invert:
     274            mask = mask_not(mask)
     275        return mask
     276
     277    @asaplog_post_dec
     278    def _print_stats(self,stats,statstr=None,label="",mask=None,unmask=False):
     279        if not isinstance(stats,dict) or len(stats) == 0:
     280            asaplog.post()
     281            asaplog.push("Invalid statistic value")
     282            asaplog.post("ERROR")
     283        maskstr = "Not available"
     284        if mask:
     285            masktype = "mask"
     286            maskstr = str(mask)
     287            if unmask: masktype = "unmask"
     288
     289        sout = label + ", " + masktype + " = " + maskstr + "\n"
     290        statvals = []
     291        if not len(statstr):
     292            statstr = stats.keys()
     293        for key in statstr:
     294            sout += key.ljust(10)
     295            statvals.append(stats.pop(key))
     296        sout += "\n"
     297        sout += ("%f "*len(statstr) % tuple(statvals))
     298        asaplog.push(sout)
     299        del sout, maskstr, masktype, statvals, key, stats, statstr, mask, label
     300
    169301
    170302    ### Page chages
     
    255387        del lastpanel,currpnum,prevpnum,start_ipanel
    256388
    257     ### refresh the page counter
    258389    ### refresh the page counter
    259390    def set_pagecounter(self,page):
     
    710841        try: self.lastspan
    711842        except AttributeError: pass
    712         else: self._remove_span(self.lastspan)
     843        else:
     844            if self.lastspan: self._remove_span(self.lastspan)
    713845
    714846        #self.lastspan = self._draw_span(self._thisregion['axes'],self._thisregion['xs'],xnow,fill="#555555",stipple="gray50")
     
    737869            xdataend = event.xdata
    738870        else:
    739             xdataend=self.xdataold
     871            xdataend = self.xdataold
    740872
    741873        self._thisregion['worldx'][1] = xdataend
     
    750882            self._selregions[srow] = []
    751883        self._selregions[srow].append(lregion)
    752         del lregion, pregion, xdataend, self.xold, self.xdataold
     884        del lregion, pregion, xdataend
    753885        sout = "selected region: "+str(self._thisregion['worldx'])+\
    754886              "(@row "+str(self._getrownum(self._thisregion['axes']))+")"
     
    761893        self._thisregion = None
    762894        self.xdataold = None
     895        self.xold = None
    763896        # finally recover region selection event
    764897        self.plotter._plotter.register('button_press',self._add_region)
Note: See TracChangeset for help on using the changeset viewer.