source: SHX/trunk/SeismicHandler/basics/tools.py @ 1062

Revision 1062, 4.5 KB checked in by klaus, 4 years ago (diff)

timeit decorator for runtime info

  • Property svn:eol-style set to native
Line 
1# -*- coding: utf-8 -*-
2
3"""
4Collection of globally used helper functions and classes.
5"""
6
7import time
8from obspy.core import AttribDict
9
10__all__ = ["Property", "Singleton","timeit","timestore"]
11
12# property wrapper
13def Property(func):
14    return property(**func())
15
16
17class Singleton(type):
18    """
19    Meta-class for singletons.
20    """
21
22    def __init__(cls, name, bases, dic):
23        super(Singleton, cls).__init__(name, bases, dic)
24        cls.instance = None
25
26    def __call__(cls, *args, **kwargs):
27        if cls.instance is None:
28            cls.instance = super(Singleton, cls).__call__(*args, **kwargs)
29
30        return cls.instance
31
32
33class AttributeBlock(object):
34    lstyles = ["solid", "short_dash", "long_dash", "dot_dash", "dot"]
35    def __init__(self, **kwargs):
36        """
37        Style attribute class. Used in command "FCT SETSTYLE"
38        """
39        attrib = AttribDict()
40        # set defaults
41        attrib.charsize = 0.012
42        attrib.color = [0, 0, 0]
43        attrib.font = "default"
44        attrib.linestyle = "solid"
45        attrib.linewidth = 1
46
47        self.style = attrib
48
49        # override with new values
50        for k in kwargs:
51            setattr(self.style, k, kwargs[k])
52
53    def __getattr__(self, name):
54        try:
55            return self.style[name.lower()]
56        except:
57            raise AttributeError()
58
59    def __setattr__(self, name, value):
60        """
61        If an attribute name is used in association it will be masked
62        transparently into the style AttribDict. In this case also consistent
63        checks will be made.
64        """
65        try:
66            if name.lower() in self.style:
67                style = self.style
68                kl = name.lower()
69                if kl not in style.keys():
70                    raise NameError("invalid style attribute: %s" % kl)
71
72                v = value
73                if v.isdigit():
74                    v = int(v)
75                else:
76                    try:
77                        v = float(v)
78                    except:
79                        pass
80
81                if kl == "linestyle":
82                    try:
83                        v = self.lstyles[v-1]
84                    except:
85                        pass
86                    if v.lower() not in self.lstyles:
87                        msg = "Invalid line-style! Valid: %s or numbers: 1-%u"
88                        print msg % (", ".join(self.lstyles), len(self.lstyles))
89                        return
90
91                if kl == "linewidth":
92                    v = int(v)
93
94                self.style[kl] = v
95                return
96        except:
97            pass
98        object.__setattr__(self, name, value)
99
100
101def timeit(method):
102    "Decorator for measuring execution time of methods."
103
104    def timed(*args, **kw):
105        ts = time.time()
106        result = method(*args, **kw)
107        te = time.time()
108        runtime = te - ts
109        try:
110            specname = method.__doc__[:6].replace(' ','-').replace('\n','-'
111                ).strip('-')
112        except:
113            specname = ""
114        if specname:
115            specname += '.'
116        name = "%s.%s%s" % (method.__module__.strip("'"),
117            specname,method.__name__.strip("'"))
118        #print '%s %2.2f sec' % (name, runtime)
119        ta = time.time()
120        timestore.add( name, runtime )
121        tt = time.time()
122        timestore.add( "timeit", tt-te + tt-ta )  # estimate tt-ta for this command
123        return result
124
125    return timed
126
127
128class TimeStore:
129    def __init__( self ):
130        self.timedict = {}
131        self.cntdict = {}
132        self.enabled = True
133    def add( self, name, runtime ):
134        if not self.enabled:
135            return
136        try:
137            self.timedict[name] += runtime
138        except:
139            self.timedict[name] = runtime
140        try:
141            self.cntdict[name] += 1
142        except:
143            self.cntdict[name] = 1
144    def clear( self ):
145        self.timedict = {}
146        self.cntdict = {}
147    def enable( self, onoff ):
148        self.enabled = onoff
149    def dump( self, sumroot=[] ):
150        for name in sorted(self.timedict.keys()):
151            print "%s  :  %7.4f (%d)" % (name,self.timedict[name],
152                self.cntdict[name])
153        if sumroot:
154            print
155            print "totals:"
156            for root in sumroot:
157                runsum = 0.
158                for name in self.timedict.keys():
159                    if root == '.' or name.startswith(root):
160                        runsum += self.timedict[name]
161                print "%s : %7.4f" % (root,runsum)
162
163timestore = TimeStore()
Note: See TracBrowser for help on using the repository browser.