-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathextract.py
More file actions
165 lines (141 loc) · 6.08 KB
/
extract.py
File metadata and controls
165 lines (141 loc) · 6.08 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
#This file will contain the mappings of data to location they are stored in.
#The location will be given as a tuple:
#(row, column, number of digits, decimal place, units)
#Please note: mappings are zero-indexed, lengths are lengths.
#note regarding decimal place: 0 means no decimal, 1, means one from the right,
#2 means two from the right, etc.
mapping = {'AP': (0, 0, 2, 0, 'None'),
'GTS': (0, 2, 3, 0, 'None'),
'Page': (0, 5, 1, 0, 'None'),
'Time': (0, 6, 4, 0, 'None'),
'Cloud': (0, 11, 2, 0, '%'),
'Windspeed': (0, 13, 1, 0, 'm/s'),
'Habitat': (1, 0, 2, 0, 'Check'),
#PROBES SOIL DATA
'SAT-HOG': (1, 2, 2, 1, 'm'),
'SAT-SUN': (1, 4, 3, 1, '*C'),
'SAT-SHA': (1, 7, 3, 1, '*C'),
'SWT1': (1, 10, 3, 1, '*C'),
'SWT2': (1, 13, 3, 1, '*C'),
#PROBES WATER DATA
'HYPRO2': (1, 16, 3, 1, '*C'),
'HYPRO4': (1, 19, 3, 1, '*C'),
'HYPRO6': (1, 22, 3, 1, '*C'),
'HYPRO8': (2, 0, 3, 1, '*C'),
'HYPRO1': (2, 3, 3, 1, '*C'),
#PROBES SUN SOIL TEMPERATURES
'STSL-S': (2, 6, 3, 1, '*C'),
'STSL-2': (2, 9, 3, 1, '*C'),
'STSL-4': (2, 12, 3, 1, '*C'),
'STSL-6': (2, 15, 3, 1, '*C'),
'STSL-8': (2, 18, 3, 1, '*C'),
'STSL-1': (2, 21, 3, 1, '*C'),
#PROBES SHADE SOIL TEMPERATURES
'STSH-S': (3, 0, 3, 1, '*C'),
'STSH-2': (3, 3, 3, 1, '*C'),
'STSH-4': (3, 6, 3, 1, '*C'),
'STSH-6': (3, 9, 3, 1, '*C'),
'STSH-8': (3, 12, 3, 1, '*C'),
'STSH-1': (3, 15, 3, 1, '*C'),
#TDS and TUR
'TDS1': (4, 6, 3, 0, 'mg/L'),
'TDS2': (4, 9, 3, 0, 'mg/L'),
'TUR1': (4, 12, 3, 0, 'NTU'),
'TUR2': (4, 15, 3, 0, 'NTU'),
#ALBEDO
#okay actually I'll do that later. I have a request from IoO's to do the images.
#IMAGES
#Targets that are DSCN numbers must end in 'IMG'
'Sun Soil IMG': (4, 18, 4, 0, 'None'),
'Shade Soil IMG': (4, 22, 4, 0, 'None'),
'First Pan IMG': (5, 22, 4, 0, 'None'),
#Do not encode the # of pans as an 'IMG'.
'PanNum': (5, 20, 2, 0, 'None'),
'VC1 IMG': (7, 22, 4, 0, 'None'),
'VC2 IMG': (8, 0, 4, 0, 'None'),
'GND CVR IMG': (8, 4, 4, 0, 'None'),
'BB1 IMG': (8, 8, 4, 0, 'None'),
'BB2 IMG': (8, 12, 4, 0, 'None'),
'Weather IMG': (9, 0, 4, 0, 'None'),
'DO/Soil pH IMG': (9, 4, 4, 0, 'None'),
'PHOS/NH4 IMG': (9, 8, 4, 0, 'None'),
'Stereo IMG': (9, 12, 4, 0, 'None'),
'5 in 1 IMG': (9, 16, 4, 0, 'None'),
'Chlorine IMG': (9, 20, 4, 0, 'None'),
#OTHER THINGS NOT IN FDSs BUT STILL IMPORTANT
#Eric is a n00b. :)
'DO': (1, 26, 5, 0, 'ppm'),
'pH': (2, 26, 4, 0, 'pH'),
'Nitrates': (3, 26, 5, 0, 'mmol'), #NOTE UNIT MAY BE INCORRECT
'Nitrites': (4, 26, 4, 0, 'mmol'),
'Ammonia': (5, 26, 5, 0, 'ppm'),
'Phosphates': (6, 26, 5, 0, 'ppt'),
'Chlorine': (7, 26, 4, 0, 'ppt'),
'Water Hardness': (8, 26, 5, 0, 'ppt'), #Units?
'Alkalinity': (9, 26, 5, 0, 'ppt'),
'Soil pH': (10, 26, 4, 0, 'pH'),
#The official (reference) AHP lists PH and SP, and
#I'm not quite sure which is soil pH and which is water pH. Help?
}
#TODO: This is woefully incomplete. Please finish the rest of the mappings
def getLoc(target):
'''Takes a target, such as 'Water pH', and returns
the location and length of the target in a .dat file.'''
if target not in mapping:
print "{0} is not a valid field.".format(target)
else:
return mapping[target][:3]
def extract(target, AP, GTS, withDec = True, asText = False):
'''Extracts the target from the specific .dat of the specified
AP number and GTS.
If withDec is True, then a decimal will be inserted according to the mapping
rules. Otherwise it will be given 'raw', i.e. if there was a decimal
already in the data, it will be returned but none will be added.
If asText is True, then a string will be returned with the units,
if available. Otherwise a float value will be returned.
Errors: If no value is found, due to lack of files or lack of data,
None is returned.
'''
from read import openFile
from ext_exceptions import isException
import re
if isException(target, AP, GTS):
from exceptions import exceptionExtract
return exceptionExtract(target, AP, GTS, withDec, asText)
stationdata = openFile(AP, GTS)
if not stationdata: #no file found
return
x, y, leng = getLoc(target)
try:
value = stationdata[x][y:y+leng]
except:
value = None
#return None if it's just whitespace.
if re.match(r'\W+$', value)is not None: #double negatives ftw.
return
if not value:
print "No {0} data was found for AP{1}-{2}.".format(target, AP, GTS)
return
else:
try:
value = float(value) #In AP13-725, there's an H that messed this up.
except:
print 'Non-numeric value read:{0} for {1} in AP{2}-{3}'.format(
value, target, AP, GTS)
return
#I don't remember what the following is for. It looks redundant.
## if value == None:
## print 'Data for this target and Sample Station are not availabe.'
## return
if withDec:
if value.is_integer(): #insert the decimal point
dec = mapping[target][3]
value /= 10**dec
if asText: #return a string with units
unit = mapping[target][4]
if unit != 'None': #if there are units
return "{0} {1}".format(value, unit)
else:
return "{0}".format(value) #just print the value as a string if no units
else: #return just the value without units and as a float
return value