-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathutilities.py
More file actions
176 lines (156 loc) · 6.21 KB
/
utilities.py
File metadata and controls
176 lines (156 loc) · 6.21 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
166
167
168
169
170
171
172
173
174
175
176
#!/usr/bin/env python
# utility file for keeping consistent language in handling parameters
####################################################################################################
# SCRIPTS
from config import *
# PACKAGES
import hashlib
import numpy as np
from copy import deepcopy
####################
### Parameter Conversions
def param_encode(param_dict):
param_str = ""
for molecule in ATMOS_MOL:
#string += molecule
concentration = param_dict[molecule]
param_str += str(concentration)
param_str += ","
param_str = param_str[:-1] #remove trailing comma
return param_str
def param_decode(param_str):
param_list = param_str.split(",")
param_dict = {}
for i, molecule in enumerate(ATMOS_MOL):
param_dict[molecule] = param_list[i]
return param_dict
def param_hash(param_dict):
string = ""
for molecule in ATMOS_MOL:
string += molecule
concentration = param_dict[molecule]
string += str(concentration)
hash_object = hashlib.md5(str.encode(string))
return hash_object.hexdigest()
def metadata_encode(meta_dict):
meta_str = ""
for key in ATMOS_METADATA:
meta_str += str(meta_dict[key])
meta_str += ','
meta_str = meta_str[:-1] #remove trailing comma
return meta_str
def metadata_decode(meta_str):
meta_list = meta_str.split(",")
meta_dict = {}
for i, key in enumerate(ATMOS_METADATA):
meta_dict[key] = meta_list[i]
return meta_dict
def pack_items(item_list):
# take a list of items and pack them into a string separated by a semicolon
packed = ';'.join(map(str, item_list))
return packed
def unpack_items(packed_items):
unpacked = packed_items.split(";")
return unpacked
####################
### Build Functions
def round_partial(value, resolution):
return round(float(value)/float(resolution)) * resolution
def calc_filler(param_dict):
filler = 1 # starting point
for molecule, concentration in param_dict.items():
concentration = float(concentration)
if molecule not in ["N2"]:
filler -= concentration
else:
continue
return round(filler, 10) #10 digits because that's the smallest digit it should go to
####################
### Explore Functions
def explore(param_dict, increment_dict, redis_db, step_size=1, search_mode="sides", explore_count="0"):
# let's say param_dict is not a list of values but a dictionary:
#param_dict = {
# "O2" : .05,
# "H2" : 0.21,
# "other" : constant_value,
# "filler" : dynamic value to help reach 100% sum
# }
#increment_dict = {
# "H2" : {.001: 0.0001, 0.01: 0.001, ...}
# }
#
#check to see if any of the neighbors are added to queue or if they've all been executed (dead end)
steps = np.concatenate((-1*(np.arange(step_size)+1),np.arange(step_size)+1))
if search_mode == "sides":
for molecule in ALTER_MOLECULES:
concentration = float(param_dict[molecule])
mol_increment_dict = increment_dict[molecule]
for b, bin in enumerate(mol_increment_dict['bins']):
if concentration < bin:
break
else:
continue
increment = mol_increment_dict['increment'][b]
if increment == 0:
continue #skip this molecule
else:
pass
for direction in steps:
neighbor = deepcopy(param_dict)
val = round_partial(concentration + direction*increment, increment)
if val > 0:
neighbor[molecule] = val
else:
continue
neighbor["N2"] = calc_filler(neighbor)
if neighbor["N2"] < 0:
# impossible space...don't add
continue
else:
# add to main queue and sql queue
#redis_db.put(value=neighbor, queue="main")
packed_list = pack_items( [param_encode(neighbor), param_hash(param_dict), explore_count] )
redis_db.put(value=packed_list, queue="main sql")
elif search_mode == "diagonals":
# say if we have 's' possible states...s=3 for step_size=1 st we can go +1, +0, or -1.
# and if we have 'd' number of dimensions to explore...dimensions is number of molecules we're exploring
# then we'll have (s^d - 1) neighbors to search for
# idea, create
next_list = [param_dict]
for molecule in ALTER_MOLECULES:
concentration = float(param_dict[molecule])
mol_increment_dict = increment_dict[molecule]
previous_list = deepcopy(next_list)
for direction in steps:
for neighbor in previous_list:
neigh = deepcopy(neighbor)
for b, bin in enumerate(mol_increment_dict['bins']):
if concentration < bin:
break
else:
continue
increment = mol_increment_dict['increment'][b]
if increment == 0:
continue #skip this molecule
else:
pass
val = round_partial(concentration + direction*increment, increment)
if val > 0:
neigh[molecule] = val
next_list.append(neigh)
else:
continue
# now have a list of all possible neighboring points
for neighbor in next_list:
neighbor["N2"] = calc_filler(neighbor)
if neighbor["N2"] < 0:
# impossible space...don't add
continue
else:
# add to main queue and sql queue
#redis_db.put(value=neighbor, queue="main")
packed_list = pack_items( [param_encode(neighbor), param_hash(param_dict), explore_count] )
redis_db.put(value=packed_list, queue="main sql")
else:
# no other search_mode created
pass