Changeset 1621
- Timestamp:
- 08/15/09 20:46:28 (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/alma/python/interactivemask.py
r1566 r1621 8 8 9 9 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() 13 17 14 18 Modify mask region by selecting a region on a plot with mouse. 15 19 """ 16 20 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 21 40 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 22 59 self.rect={} 23 60 self.xold=None … … 25 62 self.xdataold=None 26 63 self.ydataold=None 27 self.mask=None28 64 self._polygons=[] 29 self._p=None30 65 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 38 71 Parameters: 39 scan: a scantable40 72 masklist: [[min, max], [min2, max2], ...] 41 73 A list of pairs of start/end points (inclusive) … … 44 76 return an inverted mask, i.e. the regions 45 77 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. 50 80 """ 51 81 # Verify input parameters 52 if not isinstance(scan, scantable):53 msg = 'Input is not a scantable'54 raise TypeError(msg)55 82 if not (isinstance(masklist, list) or isinstance(masklist, tuple)) \ 56 83 or not isinstance(invert, bool): 57 84 msg = 'Invalid mask definition' 58 85 raise TypeError(msg) 59 60 self.scan=scan 61 62 # Create initial mask 86 87 # Create base mask 63 88 if ( len(masklist) > 0 ): 64 89 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: 66 93 self.mask=_n_bools(self.scan.nchan(),True) 67 94 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 """ 68 137 # Return if GUI is not active 69 138 if not rcParams['plotter.gui']: … … 72 141 return 73 142 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' 76 153 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 103 184 104 185 def _region_start(self,event): 105 186 # Do not fire event when in zooming/panning mode 106 mode = self. _p.figmgr.toolbar.mode187 mode = self.p._plotter.figmgr.toolbar.mode 107 188 if not mode =='': 108 189 return … … 110 191 if event.inaxes == None: return 111 192 # Select mask/unmask region with mask 112 height = self._p.canvas.figure.bbox.height()113 193 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, 116 195 'world': [event.xdata, event.ydata, 117 196 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) 122 201 123 202 def _region_draw(self,event): 124 self._p.canvas._tkcanvas.delete(self.rect['fig'])125 203 sameaxes=(event.inaxes == self.rect['axes']) 126 204 if sameaxes: … … 134 212 xnow=self.xold 135 213 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 140 217 141 218 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) 147 223 148 224 if event.inaxes == self.rect['axes']: … … 158 234 159 235 self.rect['world'][2:4] = [xdataend, ydataend] 160 self.rect['pixel'][2:4] = [xend, height -yend]236 self.rect['pixel'][2:4] = [xend, yend] 161 237 self._update_mask() 238 if self.once: self.finish_selection(callback=self.callback) 162 239 163 240 def _update_mask(self): … … 183 260 self.mask=mask_or(self.mask,newmask) 184 261 # 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() 186 264 187 265 # Plot masked regions … … 206 284 # Plot new polygons 207 285 if len(msks) > 0: 208 npanel=len(self. _p.subplots)286 npanel=len(self.p._plotter.subplots) 209 287 j=-1 210 288 for iloop in range(len(msks)*npanel): … … 213 291 if len(ifs) > 1: 214 292 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 218 321 219 322 def get_mask(self): … … 225 328 return self.mask 226 329 330
Note:
See TracChangeset
for help on using the changeset viewer.