1
1
import datetime
2
+
2
3
from fitparse .utils import scrub_method_name
3
4
4
5
# Datetimes (uint32) represent seconds since this UTC_REFERENCE
5
6
UTC_REFERENCE = 631065600 # timestamp for UTC 00:00 Dec 31 1989
6
7
7
8
8
9
class FitFileDataProcessor (object ):
10
+ """
11
+ Processor to change raw values to more comfortable ones.
12
+ Uses method cache to speed up the processing - reuse the object if used multiple times.
13
+ """
14
+
9
15
# TODO: Document API
10
16
# Functions that will be called to do the processing:
11
- #def run_type_processor(field_data)
12
- #def run_field_processor(field_data)
13
- #def run_unit_processor(field_data)
14
- #def run_message_processor(data_message)
17
+ # def run_type_processor(field_data)
18
+ # def run_field_processor(field_data)
19
+ # def run_unit_processor(field_data)
20
+ # def run_message_processor(data_message)
15
21
16
22
# By default, the above functions call these functions if they exist:
17
- #def process_type_<type_name> (field_data)
18
- #def process_field_<field_name> (field_data) -- can be unknown_DD but NOT recommended
19
- #def process_units_<unit_name> (field_data)
20
- #def process_message_<mesg_name / mesg_type_num> (data_message)
23
+ # def process_type_<type_name> (field_data)
24
+ # def process_field_<field_name> (field_data) -- can be unknown_DD but NOT recommended
25
+ # def process_units_<unit_name> (field_data)
26
+ # def process_message_<mesg_name / mesg_type_num> (data_message)
21
27
22
- # Used to memoize scrubbed method names
23
- _scrubbed_method_names = {}
28
+ def __init__ (self ):
29
+ # Used to memoize scrubbed methods
30
+ self ._method_cache = {}
24
31
25
- def _scrub_method_name (self , method_name ):
26
- """Scrubs a method name, returning result from local cache if available .
32
+ def _get_scrubbed_method (self , method_name ):
33
+ """Scrubs a method name and cache it _method_cache .
27
34
28
35
This method wraps fitparse.utils.scrub_method_name and memoizes results,
29
36
as scrubbing a method name is expensive.
@@ -32,36 +39,38 @@ def _scrub_method_name(self, method_name):
32
39
method_name: Method name to scrub.
33
40
34
41
Returns:
35
- Scrubbed method name .
42
+ Scrubbed method (bounded) .
36
43
"""
37
- if method_name not in self ._scrubbed_method_names :
38
- self ._scrubbed_method_names [method_name ] = (
39
- scrub_method_name (method_name ))
44
+ method = self ._method_cache .get (method_name , False )
45
+ if method is not False :
46
+ return method
47
+
48
+ scrubbed_method_name = scrub_method_name (method_name )
49
+ try :
50
+ method = getattr (self , scrubbed_method_name )
51
+ except AttributeError :
52
+ method = None
53
+ self ._method_cache [method_name ] = method
54
+ return method
40
55
41
- return self ._scrubbed_method_names [method_name ]
56
+ def _run_processor (self , method_name , data ):
57
+ method = self ._get_scrubbed_method (method_name )
58
+ if method is None :
59
+ return
60
+ method (data )
42
61
43
62
def run_type_processor (self , field_data ):
44
- self ._run_processor (self ._scrub_method_name (
45
- 'process_type_%s' % field_data .type .name ), field_data )
63
+ self ._run_processor ('process_type_%s' % field_data .type .name , field_data )
46
64
47
65
def run_field_processor (self , field_data ):
48
- self ._run_processor (self ._scrub_method_name (
49
- 'process_field_%s' % field_data .name ), field_data )
66
+ self ._run_processor ('process_field_%s' % field_data .name , field_data )
50
67
51
68
def run_unit_processor (self , field_data ):
52
69
if field_data .units :
53
- self ._run_processor (self ._scrub_method_name (
54
- 'process_units_%s' % field_data .units ), field_data )
70
+ self ._run_processor ('process_units_%s' % field_data .units , field_data )
55
71
56
72
def run_message_processor (self , data_message ):
57
- self ._run_processor (self ._scrub_method_name (
58
- 'process_message_%s' % data_message .def_mesg .name ), data_message )
59
-
60
- def _run_processor (self , processor_name , data ):
61
- try :
62
- getattr (self , processor_name )(data )
63
- except AttributeError :
64
- pass
73
+ self ._run_processor ('process_message_%s' % data_message .def_mesg .name , data_message )
65
74
66
75
def process_type_bool (self , field_data ):
67
76
if field_data .value is not None :
@@ -114,3 +123,11 @@ def process_units_semicircles(self, field_data):
114
123
if field_data .value is not None :
115
124
field_data .value *= 180.0 / (2 ** 31 )
116
125
field_data .units = 'deg'
126
+
127
+
128
+ _DEFAULT_PROCESSOR = FitFileDataProcessor ()
129
+
130
+
131
+ def get_default_processor ():
132
+ """Default, shared instance of processor. (Due to the method cache.)"""
133
+ return _DEFAULT_PROCESSOR
0 commit comments