Changeset 1621 for branches/alma


Ignore:
Timestamp:
08/15/09 20:46:28 (15 years ago)
Author:
Kana Sugimoto
Message:

New Development: No

JIRA Issue: No

Ready to Release: Yes

Interface Changes: Yes

What Interface Changed: input parameters changed for methods 'init', 'select_mask'.

new methods added, i.e., 'set_basemask', 'set_startevent',

'set_callback', and 'finish_selection'

Test Programs:

Put in Release Notes: Yes

Module(s): sdbaseline & sdstat

Description:

The class interactivemask is reconstructed so that it can be worked both for
statistics calculations on ASAP plotter and interactive mask selection
in sdbaseline and sdstat.
!!!NOTE!!! both sdbaseline and sdstat should be updated at the same time.
input parameters changed: 'init', 'select_mask'.
new methods: 'set_basemask', 'set_startevent', 'set_callback', and 'finish_selection'

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/alma/python/interactivemask.py

    r1566 r1621  
    88
    99        Example:
    10            new_mask=interactivemask()
    11            new_mask.select_mask(scan,masklist=[[0,10],[90,100]],invert=False)
    12            mask=new_mask.get_mask()
     10           my_mask=interactivemask(plotter,scan)
     11           my_mask.set_basemask(masklist=[[0,10],[90,100]],invert=False)
     12           # Do interactive mask selection
     13           my_mask.select_mask()
     14           finish=raw_input('Press return to finish selection.\n')
     15           my_mask.finish_selection(callback=func)
     16           mask=my_mask.get_mask()
    1317           
    1418        Modify mask region by selecting a region on a plot with mouse.
    1519        """
    1620
    17         def __init__(self):
    18                 """
    19                 Create a interactive masking object
    20                 """
     21        def __init__(self,plotter=None, scan=None):
     22                """
     23                Create a interactive masking object.
     24                Either or both 'plotter' or/and 'scan' should be defined.
     25
     26                Parameters:
     27                   plotter: an ASAP plotter object for interactive selection
     28                   scan: a scantable to create a mask interactively
     29                """
     30                # Return if GUI is not active
     31                if not rcParams['plotter.gui']:
     32                        print 'GUI plotter is disabled.\n'
     33                        print 'Exit interactive mode.'
     34                        return
     35                # Verify input parameters
     36                if scan is None and plotter is None:
     37                        msg = "Either scantable or plotter should be defined."
     38                        raise TypeError(msg)
     39
    2140                self.scan=None
     41                self.p=None
     42                self.newplot=False
     43                if scan and isinstance(scan, scantable):
     44                        self.scan=scan
     45                from asap.asapplotter import asapplotter
     46                if plotter and isinstance(plotter,asapplotter):
     47                        self.p = plotter
     48                        if self.scan is None and isinstance(self.p._data,scantable):
     49                                self.scan=self.p._data
     50                if self.scan is None:
     51                        msg = "Invalid scantable."
     52                        raise TypeError(msg)
     53
     54                self.mask=_n_bools(self.scan.nchan(),True)
     55                self.callback=None
     56                self.event=None
     57                self.once=False
     58                self.showmask=True
    2259                self.rect={}
    2360                self.xold=None
     
    2562                self.xdataold=None
    2663                self.ydataold=None
    27                 self.mask=None
    2864                self._polygons=[]
    29                 self._p=None
    3065       
    31         def select_mask(self,scan,masklist=[],invert=False):
    32                 """
    33                 Do interactive mask selection.
    34                 Calculate initial channel mask based on the parameters and modify
    35                 it interactively by adding/deleting regions with mouse drawing.
    36                 When finish modifying, press <Return> to calculate the final mask.
    37                
     66
     67        def set_basemask(self,masklist=[],invert=False):
     68                """
     69                Set initial channel mask.
     70               
    3871                Parameters:
    39                     scan:      a scantable
    4072                    masklist:  [[min, max], [min2, max2], ...]
    4173                               A list of pairs of start/end points (inclusive)
     
    4476                               return an inverted mask, i.e. the regions
    4577                               specified are excluded
    46 
    47                 Interactive region selection is available only when GUI plotter
    48                 is active. When GUI plotter is disabled, this method only
    49                 calculates a initial channel mask.
     78                You can reset the mask selection by running this method with
     79                the default parameters.
    5080                """
    5181                # Verify input parameters
    52                 if not isinstance(scan, scantable):
    53                         msg = 'Input is not a scantable'
    54                         raise TypeError(msg)
    5582                if not (isinstance(masklist, list) or isinstance(masklist, tuple)) \
    5683                   or not isinstance(invert, bool):
    5784                        msg = 'Invalid mask definition'
    5885                        raise TypeError(msg)
    59                
    60                 self.scan=scan
    61 
    62                 # Create initial mask
     86
     87                # Create base mask
    6388                if ( len(masklist) > 0 ):
    6489                        self.mask=self.scan.create_mask(masklist,invert=invert)
    65                 else:
     90                elif invert==True:
     91                        self.mask=_n_bools(self.scan.nchan(),False)
     92                else:
    6693                        self.mask=_n_bools(self.scan.nchan(),True)
    6794
     95
     96        def set_startevent(self,event):
     97                """
     98                Inherit an event from the parent function.
     99               
     100                Parameters:
     101                    event: 'button_press_event' object to be inherited to
     102                           start interactive region selection .
     103                """
     104                from matplotlib.backend_bases import MouseEvent
     105                if isinstance(event,MouseEvent) and event.name=='button_press_event':
     106                        self.event=event
     107                else:
     108                        msg="Invalid event."
     109                        raise TypeError(msg)   
     110
     111        def set_callback(self,callback):
     112                """
     113                Set callback function to run when finish_selection() is executed.
     114                    callback: The post processing function to run after
     115                              the mask selections are completed.
     116                              This will be overwritten if callback is defined in
     117                              finish_selection(callback=func)
     118                """
     119                self.callback=callback
     120
     121        def select_mask(self,once=False,showmask=True):
     122                """
     123                Do interactive mask selection.
     124                Modify masks interactively by adding/deleting regions with
     125                mouse drawing.(left-button: mask; right-button: UNmask)
     126                Note that the interactive region selection is available only
     127                when GUI plotter is active.
     128
     129                Parameters:
     130                    once:     If specified as True, you can modify masks only
     131                              once. Else if False, you can modify them repeatedly.
     132                    showmask: If specified as True, the masked regions are plotted
     133                              on the plotter.
     134                              Note this parameter is valid only when once=True.
     135                              Otherwise, maskes are forced to be plotted for reference.
     136                """
    68137                # Return if GUI is not active
    69138                if not rcParams['plotter.gui']:
     
    72141                        return
    73142
    74                 # Plot selected spectra
    75                 if not self._p or self._p.is_dead:
     143                self.once = once
     144                if self.once:
     145                        self.showmask=showmask
     146                else:
     147                        if not showmask: print 'Warning: showmask spcification is ignored. Mask regions are plotted anyway.'
     148                        self.showmask=True
     149
     150                #if not self.p._plotter or self.p._plotter.is_dead:
     151                if not self.p or self.p._plotter.is_dead:
     152                        print 'A new ASAP plotter will be loaded'
    76153                        from asap.asapplotter import asapplotter
    77                         plotter=asapplotter()
    78                         self._p = plotter._plotter
    79                 plotter.plot(self.scan)
    80                 for panel in self._p.subplots:
    81                         xmin, xmax = panel['axes'].get_xlim()
    82                         marg = 0.05*(xmax-xmin)
    83                         panel['axes'].set_xlim(xmin-marg, xmax+marg)
    84                 self._p.show()
    85                 self._plot_mask()
    86 
    87                 print ''
    88                 print 'Selected regions are shaded with yellow. (gray: projections)'
    89                 print 'Now you can modify the selection.'
    90                 print 'Draw rectangles with Left-mouse to add the regions,'
    91                 print 'or with Right-mouse to exclude the regions.'
    92                
    93                 cid = None
    94                 cid = self._p.canvas.mpl_connect('button_press_event', self._region_start)
    95                 finish=raw_input('Press return to calculate statistics.\n')
    96                 if cid is not None:
    97                         self._p.canvas.mpl_disconnect(cid)
    98 
    99                 # Finish the plot
    100                 self._p.unmap()
    101                 self._p = None
    102                 del plotter
     154                        self.p=asapplotter()
     155                        self.newplot=True
     156
     157                # Plot selected spectra if needed
     158                if self.scan != self.p._data:
     159                        # Need replot
     160                        self.p.plot(self.scan)
     161                        for panel in self.p._plotter.subplots:
     162                                xmin, xmax = panel['axes'].get_xlim()
     163                                marg = 0.05*(xmax-xmin)
     164                                panel['axes'].set_xlim(xmin-marg, xmax+marg)
     165                        self.p._plotter.show()
     166
     167                # Plot initial mask region
     168                #if self.showmask or not self.once:
     169                if self.showmask:
     170                        self._plot_mask()
     171                        print ''
     172                        print 'Selected regions are shaded with yellow. (gray: projections)'
     173                        print 'Now you can modify the selection.'
     174                        print 'Draw rectangles with Left-mouse to add the regions,'
     175                        print 'or with Right-mouse to exclude the regions.'
     176
     177
     178                if self.event != None:
     179                        self._region_start(self.event)
     180                else:
     181                        self.p._plotter.register('button_press',None)
     182                        self.p._plotter.register('button_press',self._region_start)
     183
    103184
    104185        def _region_start(self,event):
    105186                # Do not fire event when in zooming/panning mode
    106                 mode = self._p.figmgr.toolbar.mode
     187                mode = self.p._plotter.figmgr.toolbar.mode
    107188                if not mode =='':
    108189                        return
     
    110191                if event.inaxes == None: return
    111192                # Select mask/unmask region with mask
    112                 height = self._p.canvas.figure.bbox.height()
    113193                self.rect = {'button': event.button, 'axes': event.inaxes,
    114                              'fig': None, 'height': height,
    115                              'x': event.x, 'y': height - event.y,
     194                             'x': event.x, 'y': event.y,
    116195                             'world': [event.xdata, event.ydata,
    117196                                       event.xdata, event.ydata],
    118                              'pixel': [event.x, height - event.y,
    119                                        event.x, height -event.y]}
    120                 self._p.register('motion_notify', self._region_draw)
    121                 self._p.register('button_release', self._region_end)
     197                             'pixel': [event.x, event.y,
     198                                       event.x, event.y]}
     199                self.p._plotter.register('motion_notify', self._region_draw)
     200                self.p._plotter.register('button_release', self._region_end)
    122201
    123202        def _region_draw(self,event):
    124                 self._p.canvas._tkcanvas.delete(self.rect['fig'])
    125203                sameaxes=(event.inaxes == self.rect['axes'])
    126204                if sameaxes:
     
    134212                        xnow=self.xold
    135213                        ynow=self.yold
    136                        
    137                 self.rect['fig'] = self._p.canvas._tkcanvas.create_rectangle(
    138                         self.rect['x'], self.rect['y'],
    139                         xnow, self.rect['height'] - ynow)
     214
     215                self.p._plotter.figmgr.toolbar.draw_rubberband(event, xnow, ynow, self.rect['x'], self.rect['y'])
     216
    140217
    141218        def _region_end(self,event):
    142                 height = self._p.canvas.figure.bbox.height()
    143                 self._p.register('motion_notify', None)
    144                 self._p.register('button_release', None)
    145                
    146                 self._p.canvas._tkcanvas.delete(self.rect['fig'])
     219                self.p._plotter.register('motion_notify', None)
     220                self.p._plotter.register('button_release', None)
     221
     222                self.p._plotter.figmgr.toolbar.release(event)
    147223               
    148224                if event.inaxes == self.rect['axes']:
     
    158234                       
    159235                self.rect['world'][2:4] = [xdataend, ydataend]
    160                 self.rect['pixel'][2:4] = [xend, height - yend]
     236                self.rect['pixel'][2:4] = [xend, yend]
    161237                self._update_mask()
     238                if self.once: self.finish_selection(callback=self.callback)
    162239
    163240        def _update_mask(self):
     
    183260                        self.mask=mask_or(self.mask,newmask)
    184261                # Plot masked regions
    185                 self._plot_mask()
     262                #if self.showmask or not self.once: self._plot_mask()
     263                if self.showmask: self._plot_mask()
    186264
    187265        # Plot masked regions
     
    206284                # Plot new polygons
    207285                if len(msks) > 0:
    208                         npanel=len(self._p.subplots)
     286                        npanel=len(self.p._plotter.subplots)
    209287                        j=-1
    210288                        for iloop in range(len(msks)*npanel):
     
    213291                                if len(ifs) > 1:
    214292                                        for k in xrange(len(ifs)-1):
    215                                                 self._polygons.append(self._p.subplots[j]['axes'].axvspan(projs[k][i][0],projs[k][i][1],facecolor='#aaaaaa'))                   
    216                                 self._polygons.append(self._p.subplots[j]['axes'].axvspan(msks[i][0],msks[i][1],facecolor='yellow'))
    217                 self._p.canvas.draw()
     293                                                self._polygons.append(self.p._plotter.subplots[j]['axes'].axvspan(projs[k][i][0],projs[k][i][1],facecolor='#aaaaaa'))                   
     294                                self._polygons.append(self.p._plotter.subplots[j]['axes'].axvspan(msks[i][0],msks[i][1],facecolor='yellow'))
     295                self.p._plotter.canvas.draw()
     296
     297        def finish_selection(self, callback=None):
     298                if callback: self.callback=callback
     299                if self.callback: self.callback()
     300                self.p._plotter.register('button_press',None)
     301                # Finish the plot
     302                if not self.newplot:
     303                        self.clear_polygon()
     304                else:
     305                        self.p._plotter.unmap()
     306                        self.p._plotter = None
     307                        del self.p
     308                        self.p=None
     309
     310
     311        def clear_polygon(self):
     312                """
     313                Erase masks plots from the plotter.
     314                """
     315                if len(self._polygons)>0:
     316                        # Remove old polygons
     317                        for polygon in self._polygons: polygon.remove()
     318                        self.p._plotter.show()
     319                        self._polygons=[]
     320
    218321
    219322        def get_mask(self):
     
    225328                return self.mask
    226329
     330
Note: See TracChangeset for help on using the changeset viewer.