Changeset 401


Ignore:
Timestamp:
06/08/2011 06:48:31 PM (12 years ago)
Author:
marcus
Message:
  • multiple traces
  • relative/absolute time-axis
  • station/component information
  • minor improvements
File:
1 edited

Legend:

Unmodified
Added
Removed
  • SHX/trunk/sandbox/traceplotter.py

    r399 r401  
    88import os 
    99import wx.lib.scrolledpanel as SP 
     10from obspy.core import UTCDateTime 
    1011from SeismicHandler.core import read 
    1112from obspy.sh.core import fromUTCDateTime 
    1213 
     14# width of station info 
     15STATION_INFO = 75 
     16# border on right side 
     17BORDER = 15 
     18 
     19class Traces(object): 
     20    def __init__(self): 
     21        self.traces = [] 
     22        self.ids = [] 
     23 
     24    def add(self, trace): 
     25        self.traces.append(trace) 
     26 
     27    def remove(self, trace): 
     28        pass 
     29     
     30    def pop(self, trace): 
     31        pass 
     32 
     33    def __iter__(self): 
     34        for t in self.traces: 
     35            yield t 
     36 
     37    def __len__(self): 
     38        return len(self.traces) 
     39 
     40    def __getitem__(self, item): 
     41        return self.traces[item] 
     42 
    1343class MyPanel(SP.ScrolledPanel): 
    1444    def __init__(self, parent, fname=None): 
     45        self.traces = Traces() 
     46 
    1547        SP.ScrolledPanel.__init__(self, parent, style=wx.BORDER_SIMPLE) 
    1648 
     
    2254 
    2355        self.refresh = False 
     56        self.relativeAxis = False 
    2457        self.load(fname) 
    2558        self.OnPaint(None) 
    2659        self.SetFocus() 
    2760 
     61    def _debug(self, *args): 
     62        print time.time(), " ".join([str(i) for i in args]) 
     63 
     64    def getTraceUnderCursor(self, y): 
     65        try: 
     66            return self.traces[int(float(y)/self.heigth*len(self.traces))] 
     67        except IndexError: 
     68            return self.traces[-1] 
     69 
    2870    def OnMotion(self, evt): 
    29         duration = self.end - self.start 
    30         x = evt.GetX() 
    31  
    32         t = x * duration / self.width 
    33  
    34         self.parent.SetStatusText(fromUTCDateTime(self.start + t)) 
    35  
     71        if not self.relativeAxis or len(self.traces) == 1: 
     72            duration = self.end - self.start 
     73            start = self.start 
     74        else: 
     75            # get trace beneath cursor 
     76            y = evt.GetY() 
     77            t = self.getTraceUnderCursor(y) 
     78             
     79            start = t.stats.starttime 
     80            duration = t.stats.endtime - t.stats.starttime 
     81 
     82        x = evt.GetX() - STATION_INFO 
     83        t = x * duration / (self.width - STATION_INFO - BORDER) 
     84        timestamp = start + t 
     85 
     86        self.parent.SetStatusText(fromUTCDateTime(timestamp)) 
     87 
     88        # let the event propagate 
    3689        evt.Skip() 
    3790 
    3891    def load(self, fname=None): 
    39         print time.time(), "Loading %s..." % fname 
     92        self._debug("Loading %s..." % fname) 
    4093        try: 
    4194            st = read(fname) 
    42             self.tr = st[0] 
     95            trace = st[0] 
     96            self.traces.add(trace) 
     97            self.resetTimeRange() 
    4398        except Exception, e: 
    44             print time.time(), e.message 
    45  
    46         if hasattr(self, "start"): 
    47             delattr(self, "start") 
    48             delattr(self, "end") 
     99            msg = e.message and e.message or "File not readable!" 
     100            dlg = wx.MessageDialog(self, msg, "An error occured!", wx.OK | wx.ICON_ERROR) 
     101            dlg.ShowModal() 
     102            dlg.Destroy() 
     103 
     104            self._debug(e.message) 
     105 
     106    def resetTimeRange(self): 
     107        min = UTCDateTime() # now 
     108        max = UTCDateTime(0) # 1970 
     109        maxlength = 0 
     110 
     111        for t in self.traces: 
     112            if t.stats.starttime < min: 
     113                min = t.stats.starttime 
     114            if t.stats.endtime > max: 
     115                max = t.stats.endtime 
     116            # needed for relative time axis 
     117            l = t.stats.endtime - t.stats.starttime 
     118            if l > maxlength: 
     119                maxlength = l 
     120 
     121        self.start = min 
     122        self.end = max 
     123        self.maxlength = maxlength 
    49124 
    50125    def OnIdle(self, evt): 
     
    58133    def Paint(self): 
    59134        width, height = self.GetClientSize() 
     135        numTraces = len(self.traces) 
     136        theight = height // numTraces 
    60137        self.width = width 
    61  
    62         start = self.start = getattr(self, "start", self.tr.stats.starttime) 
    63         end = self.end = getattr(self, "end", self.tr.stats.endtime) 
    64  
    65         print time.time(), "Preparing plotting data..." 
    66         self.tr.shxPrepareImageData(width, height, (start, end), zoom=0.9) 
    67  
    68         bitmap = wx.EmptyBitmap(width, height) 
    69         buffer = wx.MemoryDC(bitmap) 
    70         # smoothed graphics, slower 
    71 #        dc = wx.GCDC(buffer) 
    72         dc = buffer 
    73         dc.SetBrush(wx.TRANSPARENT_BRUSH) 
    74         dc.Clear() 
    75  
    76         dc.SetPen(wx.Pen((45,45,45), 1)) 
    77  
    78         dc.BeginDrawing() 
    79         dc.DrawLineList(self.tr.shxImageData) 
    80         dc.EndDrawing() 
    81  
    82         plotStartSec = self.tr.stats.starttime - start 
    83         offsetX = 0 
    84         if plotStartSec: 
    85             # re-calculate offset 
    86             portion = plotStartSec / (end - start) 
    87             offsetX = portion * width 
    88             print time.time(), portion, offsetX 
    89  
     138        self.heigth = height 
     139        pltwidth = width - STATION_INFO - BORDER 
     140 
     141        # canvas holds the final figure 
     142        bmap = wx.EmptyBitmap(width, height) 
     143        canvas = wx.MemoryDC(bmap) 
     144        canvas.SetBrush(wx.TRANSPARENT_BRUSH) 
     145        canvas.Clear() 
     146        canvas.SetFont(wx.Font(8, wx.SWISS, wx.NORMAL, wx.NORMAL)) 
     147 
     148        for i, t in enumerate(self.traces): 
     149            if not self.relativeAxis: 
     150                start = self.start 
     151                end = self.end 
     152            else: 
     153                start = t.stats.starttime 
     154                end = start + self.maxlength 
     155 
     156            self._debug("Preparing plotting data...", t.id) 
     157            t.shxPrepareImageData(pltwidth, theight, (start, end), zoom=0.9) 
     158 
     159            # make trace graphics sketch 
     160            bitmap = wx.EmptyBitmap(pltwidth, theight) 
     161            buffer = wx.MemoryDC(bitmap) 
     162            # smoothed graphics, slower 
     163    #        dc = wx.GCDC(buffer) 
     164            dc = buffer 
     165            dc.SetBrush(wx.TRANSPARENT_BRUSH) 
     166            dc.Clear() 
     167 
     168            dc.SetPen(wx.Pen((45,45,45), 1)) 
     169 
     170            dc.BeginDrawing() 
     171            dc.DrawLineList(t.shxImageData) 
     172            dc.EndDrawing() 
     173 
     174            # add trace picture to canvas 
     175            plotStartSec = t.stats.starttime - start 
     176            offsetX = 0 
     177            if plotStartSec and not self.relativeAxis: 
     178                # re-calculate offset 
     179                portion = plotStartSec / (end - start) 
     180                offsetX = portion * pltwidth 
     181                self._debug(portion, offsetX) 
     182 
     183            # copy data 
     184            canvas.Blit(offsetX+STATION_INFO, i*theight, width, height, buffer, 0, 0, wx.AND) 
     185            txt = "%d: %s %s" % (i+1, t.stats.station, t.stats.channel[-1]) 
     186            _, h, _, _ = canvas.GetFullTextExtent(txt) 
     187            canvas.DrawText(txt, 5, i*theight+theight//2-h//2) 
     188 
     189        # make it visible 
    90190        dc2 = wx.AutoBufferedPaintDCFactory(self) 
    91191        dc2.Clear() 
    92         dc2.Blit(offsetX, 0, width, height, buffer, 0, 0, wx.AND) 
     192        dc2.Blit(0, 0, width, height, canvas, 0, 0) 
     193 
     194    def onTimeAxis(self, evt): 
     195        recent = self.relativeAxis 
     196        self.relativeAxis = evt.GetString() == "relative" 
     197        if recent != self.relativeAxis: 
     198            self.OnPaint(evt) 
    93199 
    94200class MyFrame(wx.Frame): 
    95     def __init__(self, parent, title): 
    96         wx.Frame.__init__(self, parent, title=title, size=(640,280), style=wx.DEFAULT_FRAME_STYLE | wx.FULL_REPAINT_ON_RESIZE) 
     201    def __init__(self, parent, title, size=(640,280)): 
     202        wx.Frame.__init__(self, parent, title=title, size=size, style=wx.DEFAULT_FRAME_STYLE | wx.FULL_REPAINT_ON_RESIZE) 
    97203        try: 
    98204            fname = sys.argv[1] 
     
    100206        except IndexError: 
    101207            fname = None 
     208 
    102209        self.canvas = MyPanel(self, fname) 
    103210        self.CreateStatusBar() 
     
    106213        menuBar = wx.MenuBar() 
    107214        firstmenu = wx.Menu() 
    108         read = wx.MenuItem(firstmenu, wx.NewId(), 'Re&ad...\tr') 
     215        readdb = wx.MenuItem(firstmenu, wx.NewId(), 'Re&ad...\tr') 
     216        readdb.SetBitmap(wx.ArtProvider.GetBitmap(wx.ART_FOLDER_OPEN, wx.ART_OTHER, (16, 16))) 
     217        self.Bind(wx.EVT_MENU, self.onReadDb, id=readdb.GetId()) 
     218        firstmenu.AppendItem(readdb) 
     219 
     220        read = wx.MenuItem(firstmenu, wx.NewId(), 'Read &file...\tCTRL+R') 
     221        read.SetBitmap(wx.ArtProvider.GetBitmap(wx.ART_FILE_OPEN, wx.ART_OTHER, (16, 16))) 
    109222        self.Bind(wx.EVT_MENU, self.onRead, id=read.GetId()) 
    110223        firstmenu.AppendItem(read) 
     224 
    111225        quit = wx.MenuItem(firstmenu, wx.NewId(), '&Quit\tCtrl+Q') 
     226        quit.SetBitmap(wx.ArtProvider.GetBitmap(wx.ART_QUIT, wx.ART_OTHER, (16, 16))) 
    112227        self.Bind(wx.EVT_MENU, self.onQuit, id=quit.GetId()) 
    113228        firstmenu.AppendItem(quit) 
     
    125240#        self.Bind(wx.EVT_CHAR_HOOK, self.onKeyDown) 
    126241 
     242        self.toolbar = tb = self.CreateToolBar(wx.TB_TEXT | wx.TB_NOICONS, -1) 
     243        msg = ' time-axis ' 
     244        tb.AddControl(wx.StaticText(tb, -1, msg)) 
     245        timeaxis = wx.Choice(tb, wx.NewId(), (-1, -1), (-1, -1), ["absolute", "relative"]) 
     246        tb.AddControl(timeaxis) 
     247        tb.Realize() 
     248        self.Bind(wx.EVT_CHOICE, self.canvas.onTimeAxis, timeaxis) 
     249 
    127250        self.Show() 
    128251 
     
    132255            self.onRead(evt) 
    133256        else: 
    134             print time.time(), "key code", kc 
     257            print self._debug("key code", kc) 
    135258 
    136259    def onQuit(self, evt): 
     
    156279            self.canvas.load(fqpn) 
    157280 
     281    def onReadDb(self, evt): 
     282        dlg = wx.MessageDialog(self, "not implemented yet", "An error occured!", wx.OK) 
     283        dlg.ShowModal() 
     284        dlg.Destroy() 
     285 
    158286def main(): 
    159287    app = wx.App(False) 
    160     _ = MyFrame(None, 'Trace Plotter Test') 
     288    _ = MyFrame(None, 'Trace Plotter Test', wx.DisplaySize()) 
    161289    app.MainLoop() 
    162290 
Note: See TracChangeset for help on using the changeset viewer.