Changeset 1141


Ignore:
Timestamp:
25.01.2016 17:07:22 (4 years ago)
Author:
klaus
Message:

SHX magnification window

Location:
SHX/trunk/SeismicHandler
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • SHX/trunk/SeismicHandler/cmdscripts/UI.SHC

    r1139 r1141  
    22wdw/gc=x1h/main create xh1 0. 6.8 33.9 22. 
    33uitrigger openparams 
     4uitrigger openmagnify 
    45 
    56switch/global history on 
  • SHX/trunk/SeismicHandler/commands/uitrigger.py

    r1129 r1141  
    2727        event = self.parameters[0].lower() 
    2828         
    29         if event == 'openparams': 
     29        if event in ('openparams','openmagnify'): 
    3030            try: 
    31                 ui_event("openparams") 
     31                ui_event(event) 
    3232            except: 
    3333                raise ShxError("Graphics mode not active!") 
  • SHX/trunk/SeismicHandler/modules/wx_.py

    r1139 r1141  
    1515                                ui_event, log_message, get_style#, get_runtime 
    1616from SeismicHandler.config import get_runtime 
    17 from SeismicHandler.core import Traces, Overlays 
     17from SeismicHandler.core import Traces, Overlays, traces_from_list 
    1818from SeismicHandler.basics.codes import NAME, VERSION 
    1919from SeismicHandler.basics.tools import get_default_attrib, timeit, timestore 
     
    3939# holds window instance 
    4040plotter = None 
     41 
     42class magnifyCanvas(wx.Panel): 
     43    """ 
     44    A drawing canvas for the magnification trace. It has methods similar to 
     45    the traceCanvas class, but the methods are simpler due the fact that there 
     46    is only one trace displayed. On mouse operations there is no need for the 
     47    y (vertical) coordinate to be evaluated. Subclassing therefore is difficult 
     48    or the code must be reorganized. It is not advisable to run this in a 
     49    separate thread, the message communication could be too slow for immediate 
     50    reactions to mouse input. 
     51    """ 
     52    def __init__( self, parent ): 
     53        wx.Panel.__init__( self, parent, 
     54            style=wx.BORDER_SIMPLE|wx.NO_FULL_REPAINT_ON_RESIZE) 
     55        self.Bind(wx.EVT_PAINT, self.OnPaint) 
     56        self.Bind(wx.EVT_SIZE, self.OnSize) 
     57        self.Bind(wx.EVT_MOTION, self.OnMouseMotion) 
     58        self.Bind(wx.EVT_LEFT_DOWN, self.OnMouseLeftDown) 
     59        self.Bind(wx.EVT_LEFT_UP, self.OnMouseLeftUp) 
     60        self._magn_bitmap = None 
     61        self.trc = None 
     62        self.pixwidth = None 
     63        self.pixheight = None 
     64        self.pixel_duration = None 
     65        self._xor_line = None 
     66        self._last_defined_phase = None 
     67        self._mousedouble = None 
     68        self.clearWindow() 
     69     
     70    def OnPaint( self, e ): 
     71        if self._magn_bitmap: 
     72            dc = wx.BufferedPaintDC(self, self._magn_bitmap) 
     73     
     74    def OnSize( self, e ): 
     75        self.pixwidth, self.pixheight = self.GetVirtualSize() 
     76        self.refresh() 
     77     
     78    def OnMouseMotion(self, evt): 
     79        if not self.trc: 
     80            return 
     81        x, y = evt.GetPositionTuple() 
     82        abstime, reltime = self._fromScreenCoo( x,  mode='both' ) 
     83        # draw XOR marker 
     84        if evt.LeftIsDown(): 
     85            self._drawXorLine( x ) 
     86        # Put text instatus line of plotter window 
     87        stext = "%s - %g - %s - Z:%3.1f" % (fromUTCDateTime(abstime),reltime, 
     88            self.trc.id,(self.trc.stats.endtime-self.trc.stats.starttime)) 
     89        plotter.SetStatusText( stext ) 
     90        # let the event propagate 
     91        evt.Skip() 
     92 
     93    def OnMouseLeftDown(self, evt): 
     94        "Left moune button pressed down." 
     95        x, y = evt.GetPositionTuple() 
     96        abstime = self._fromScreenCoo( x,  mode='abs' ) 
     97        if self.trc: 
     98            cphase = self._closePhase( abstime ) 
     99            if cphase: 
     100                station = "%s.%s" % (self.trc.stats.network, 
     101                    self.trc.stats.station) 
     102                station = station.upper() 
     103                _sendShCommand( 
     104                    "@PHASE CLEAR %s %s %s" % (cphase[0],station,cphase[1]) \ 
     105                    +"\n@PHASE DEFAULT_PHASE %s" % cphase[0] 
     106                ) 
     107                self._last_defined_phase = cphase[0] 
     108                #self._drawSinglePick( trace, tracetime,color='white' ) 
     109                self.refresh() 
     110        evt.Skip() 
     111 
     112    def OnMouseLeftUp(self, evt): 
     113        "Left mouse button released." 
     114        if not self.trc: 
     115            return 
     116        self._drawXorLine( None )  # clear possibly existing XOR line. 
     117        x, y = evt.GetPositionTuple() 
     118        abstime, reltime = self._fromScreenCoo( x,  mode='both' ) 
     119        station = "%s.%s" % (self.trc.stats.network,self.trc.stats.station) 
     120 
     121        # Send SH command to define/clear phase if not waiting for user input. 
     122        if self._mousedouble: 
     123            if self._last_defined_phase: 
     124                _sendShCommand( "@PHASE CLEAR %s %s manual" % ( 
     125                    self.last_defined_phase,station.upper()) ) 
     126        else: 
     127            _sendShCommand( "@PHASE DEFINE %s %s ;;; %s" % (station.upper(), 
     128                fromUTCDateTime(abstime),self.trc.stats.channel[-1].upper()), 
     129                name="mouse evt" ) 
     130            #self._drawSinglePick( trace, tracetime ) 
     131            self.refresh() 
     132        self.mousedouble = False 
     133        evt.Skip() 
     134 
     135    def refresh( self ): 
     136        self._drawMagnifyTrace() 
     137        self._drawPicks() 
     138 
     139    def _closePhase( self, abstime ): 
     140        "Return name and type of closest phase or None." 
     141        if not self.trc: 
     142            return None 
     143        phaselist = PhaseList() 
     144        if not self.pixel_duration: 
     145            return None 
     146        toltime = 2*self.pixel_duration 
     147        station = "%s.%s" % (self.trc.stats.network,self.trc.stats.station) 
     148        for phase in phaselist.getPhaseList(station): 
     149            tdiff = abs( phase.picktime-abstime ) 
     150            if tdiff < toltime: 
     151                return (phase.name,phaselist.picktypeName(phase.picktype)) 
     152        return None 
     153     
     154    def _drawMagnifyTrace( self ):         
     155        # Bitmap holding the final figure, canvas->DC drawing to this bitmap. 
     156        if self.trc == None: 
     157            self.clearWindow() 
     158            return 
     159        norm = max( abs(max(self.trc.data)), abs(min(self.trc.data)) ) 
     160        amplscale = 1./norm * self.pixheight/2. 
     161        self._magn_bitmap = wx.EmptyBitmap(self.pixwidth, self.pixheight) 
     162        mdc = wx.MemoryDC(self._magn_bitmap) 
     163        mdc.SetBrush(wx.TRANSPARENT_BRUSH) 
     164        mdc.Clear() 
     165        mdc.SetFont(wx.Font(8, wx.SWISS, wx.NORMAL, wx.NORMAL)) 
     166        mdc.SetPen(wx.Pen((0,0,0), 1)) 
     167        mdc.BeginDrawing() 
     168        mdc.DrawLines( 
     169            zip( 
     170                np.linspace( 0., self.pixwidth, len(self.trc.data) ), 
     171                self.trc.data*amplscale + self.pixheight/2 
     172            ) 
     173        ) 
     174        mdc.EndDrawing() 
     175        del mdc 
     176        self.Refresh() 
     177        self.Update() 
     178     
     179    def _drawPicks( self ): 
     180        if self.trc == None: 
     181            return 
     182        phaselist = PhaseList() 
     183        _picks = {} 
     184        sname = "%s.%s" % (self.trc.stats.network,self.trc.stats.station) 
     185        for phase in phaselist.getPhaseList(sname): 
     186            if phase.comp and self.trc.stats.channel[-1] != phase.comp: 
     187                continue 
     188            pcol = phaselist.picktypeColor( phase.picktype ) 
     189            if pcol not in _picks.keys(): 
     190                _picks[pcol] = [] 
     191            _picks[pcol].append( 
     192                ( phase.name, self._toScreenCoo(phase.picktime) ) 
     193            ) 
     194        dc = wx.ClientDC(self) 
     195        dc.SetBrush(wx.TRANSPARENT_BRUSH) 
     196        dc.SetFont( wx.Font( 8, wx.DEFAULT, wx.NORMAL, wx.NORMAL ) ) 
     197        pickborder = 10 
     198        yup = self.pixheight - pickborder 
     199        ydn = pickborder 
     200        # draw picks 
     201        for pcolor in _picks.keys(): 
     202            dc.SetPen(wx.Pen(pcolor, 1)) 
     203            dc.SetTextForeground(pcolor) 
     204            for pick in _picks[pcolor]: 
     205                pname, xcoo = pick 
     206                dc.DrawLine( xcoo, yup, xcoo, ydn ) 
     207                if pname != '_Mark_': 
     208                    dc.DrawText(pname, xcoo + 2, ydn - 10) 
     209     
     210    def _drawXorLine( self, xcoo=None ): 
     211        """Draws line in XOR mode. Deletes previous line. To only clear old 
     212        element, pass None. 
     213        Should also draw into backing store bitmap (self._bitmap). Now, 
     214        a repaint doesn't restore the XOR drawing, resulting in a doubled 
     215        element. 
     216        """ 
     217        color = 'orange' 
     218        size = 1 
     219        pickborder = 10 
     220        yup = self.pixheight - pickborder 
     221        ydn = pickborder 
     222        if xcoo == None: 
     223            coo = (None,None,None,None) 
     224        else: 
     225            coo = (xcoo,ydn,xcoo,yup) 
     226        dc = wx.ClientDC(self) 
     227        dc.SetLogicalFunction( wx.XOR ) 
     228        dc.SetPen( wx.Pen(color,size,wx.SOLID) ) 
     229        dc.SetBrush( wx.Brush(color,wx.TRANSPARENT) ) 
     230        if self._xor_line != None: 
     231            # Clear old line. 
     232            dc.DrawLine( *self._xor_line ) 
     233        if coo[0] == None: 
     234            self._xor_line = None 
     235        else: 
     236            # Draw new rectangle. 
     237            dc.DrawLine( *coo ) 
     238            self._xor_line = coo 
     239 
     240    def magnifyTrace( self, trc, boxwidth=None, boxcenter=None, boxend=None ): 
     241        if trc == None: 
     242            self.clearWindow() 
     243        self.pixwidth, self.pixheight = self.GetVirtualSize() 
     244        self.pixel_duration = self._fromScreenCoo( 1, mode='rel' ) 
     245        if boxcenter != None: 
     246            if not boxwidth: 
     247                return 
     248            w2 = boxwidth/2 
     249            torig = trc.get_info('t-origin') 
     250            if torig: 
     251                boxcenter -= torig 
     252            ta = boxcenter - w2 
     253            tb = boxcenter + w2 
     254            self.trc = trc.slice( ta, tb ) 
     255        elif boxend != None: 
     256            if not boxwidth: 
     257                return 
     258            torig = trc.get_info('t-origin') 
     259            if torig: 
     260                boxend -= torig 
     261            ta = boxend - boxwidth 
     262            self.trc = trc.slice( ta, boxend ) 
     263        else: 
     264            self.trc = trc 
     265        self._drawMagnifyTrace() 
     266        self._drawPicks() 
     267     
     268    def clearWindow( self ): 
     269        dc = wx.AutoBufferedPaintDCFactory(self) 
     270        dc.Clear() 
     271        return 
     272     
     273    def _toScreenCoo( self, abstime ): 
     274        if not self.trc or not self.pixwidth: 
     275            return 0. 
     276        return ((abstime-self.trc.stats.starttime) \ 
     277            /(self.trc.stats.endtime-self.trc.stats.starttime) * self.pixwidth) 
     278     
     279    def _fromScreenCoo( self, xpix, mode='abs' ): 
     280        if not self.trc or not self.pixwidth: 
     281            return 0. 
     282        reltime = (float(xpix)/float(self.pixwidth)) \ 
     283            * (self.trc.stats.endtime-self.trc.stats.starttime) 
     284        if mode == 'abs': 
     285            return self.trc.stats.starttime + reltime 
     286        elif mode == 'rel': 
     287            return reltime 
     288        else: 
     289            return (self.trc.stats.starttime + reltime,reltime) 
     290         
     291         
    41292 
    42293class traceCanvas(SP.ScrolledPanel): 
     
    252503                self.last_defined_phase = cphase[0] 
    253504                self._drawSinglePick( trace, tracetime,color='white' ) 
     505                if plotter.magnify: 
     506                    plotter.magnify.canvas.refresh() 
    254507            self._drawPicksAndZoom() 
    255508        evt.Skip() 
     
    304557                        shx_graphics.midpoint, size=2 ) 
    305558                    dragwidth = x - self.dragStart[0] 
     559                    # data for magnify trace 
     560                    if plotter and plotter.magnify: 
     561                        plotter.magnify.canvas.magnifyTrace( trace, 
     562                            boxend=timestamp, 
     563                            boxwidth=dragwidth*self.pixel_duration ) 
    306564                else: 
    307565                    _start = [x-self.zoomwdwwidth/2,y] 
     
    310568                        shx_graphics.midpoint, size=2 ) 
    311569                    dragwidth = _end[0] - _start[0] 
     570                    if plotter and plotter.magnify: 
     571                        plotter.magnify.canvas.magnifyTrace( trace, 
     572                            boxcenter=timestamp, 
     573                            boxwidth=dragwidth*self.pixel_duration ) 
    312574            # draw position line 
    313575            elif evt.LeftIsDown(): 
     
    371633                erel = end - trace.stats.starttime + trace.get_info('t-origin') 
    372634                plotter.setZoomWindow( trace.index(True), srel, erel ) 
     635                # content of magnify window 
     636                if plotter.magnify: 
     637                    plotter.magnify.canvas.magnifyTrace(trace.slice(start,end)) 
     638            elif plotter.magnify: 
     639                plotter.magnify.canvas.magnifyTrace( None )  # clear 
    373640 
    374641    def OnMouseLeftUp(self, evt): 
     
    400667                name="mouse evt" ) 
    401668            self._drawSinglePick( trace, tracetime ) 
     669            if plotter.magnify: 
     670                plotter.magnify.canvas.refresh() 
    402671        self.mousedouble = False 
    403672 
     
    13141583 
    13151584 
     1585class magnifyWindow(wx.Frame): 
     1586 
     1587    def __init__( self, parent, title, size=(640,100), position=(0,0) ): 
     1588        wx.Frame.__init__(self, parent, title=title, size=size, 
     1589            style=wx.DEFAULT_FRAME_STYLE | wx.FULL_REPAINT_ON_RESIZE | 
     1590            wx.FRAME_FLOAT_ON_PARENT) 
     1591        self.SetPosition( position ) 
     1592        self.canvas = magnifyCanvas( self ) 
     1593        self.Disable() 
     1594        self.Show() 
     1595        self.Enable() 
     1596 
     1597 
    13161598class plotterWindow(wx.Frame): 
    13171599    """ 
     
    13471629        self.flag_overlap = True 
    13481630        self.pardialog = None 
     1631        self.magnify = None 
     1632     
     1633    def openMagnifyWindow( self, e ): 
     1634        self.magnify = magnifyWindow( None, 'SHX magnify' ) 
    13491635     
    13501636    def showMessage( self, msg, error=False ): 
     
    13981684        self.addEntry( tracesMenu, 'Delete Selected Trace', 
    13991685            'Delete trace with zoom window', self.OnDeleteTrace ) 
     1686        self.addEntry( tracesMenu, 'Delete Selected Station', 
     1687            'Delete all traces of this station', self.OnDeleteStation ) 
    14001688        self.addEntry( tracesMenu, 'Delete Selected And Above', 
    14011689            'Delete trace with zoom window and all above', 
     
    15471835        else: 
    15481836            _sendShCommand( "del %d" % self._seltrace ) 
     1837     
     1838    def OnDeleteStation( self, e ): 
     1839        if self._seltrace == None: 
     1840            self.showMessage( "no trace selected" ) 
     1841            return 
     1842        trclist = traces_from_list( "%d" % self._seltrace ) 
     1843        if len(trclist) != 1: 
     1844            self.showMessage( "Program bug: should select only one trace" ) 
     1845            return 
     1846        trc = trclist[0] 
     1847        _sendShCommand( "del _station(%s)" % trc.stats.station ) 
    15491848 
    15501849    def OnDeleteTraceAndAbove( self, e ): 
     
    16691968        cmd = "shx_menu_fk %g %g %s %s %s" % (timea,timeb,frq,(10.*frq), 
    16701969            ap.getValueAsString('fk_max_slowness')) 
    1671         print "dbg: fkcmd:", cmd 
    16721970        _sendShCommand( cmd ) 
    16731971    def OnBeam( self, e ): 
     
    17192017        cmd = "param savetraces %s\n" % sloutfile\ 
    17202018            +"param saveascmd %s /append" % sloutfile 
    1721         print "dbg: cmd:", cmd 
    17222019        _sendShCommand( cmd ) 
    17232020     
     
    17352032        cmd = "param savetraces %s\n" % sloutfile\ 
    17362033            +"param saveascmd %s /append" % sloutfile 
    1737         print "dbg: cmd:", cmd 
    17382034        _sendShCommand( cmd ) 
    17392035     
     
    20222318subscribe_ui_event(__openparams, "openparams") 
    20232319 
     2320@ui_events 
     2321def __openmagnify(unused): 
     2322    """ 
     2323    Open magnify window. 
     2324    """ 
     2325    global plotter 
     2326    if plotter and plotter.magnify == None: 
     2327        wx.CallAfter(plotter.openMagnifyWindow, None) 
     2328subscribe_ui_event(__openmagnify, "openmagnify") 
     2329 
Note: See TracChangeset for help on using the changeset viewer.