-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathRGB_data.py
201 lines (161 loc) · 8.73 KB
/
RGB_data.py
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
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
@authors: Armi Tiihonen, Felipe Oviedo, Shreyaa Raghavan, Zhe Liu
MIT Photovoltaics Laboratory
"""
import os
import pandas as pd
import seaborn as sns
from scipy.integrate import simps
import numpy as np
#Classes and Functions
#Class RGB_data points at the moment at average RGB values only, future version
#will define
#file_name during instantiation
class RGB_data:
def __init__(self, folder, compositions, cutoff = None, is_calibrated = True, is_rgb = True):
if (is_calibrated and is_rgb):
filenames = ['sample_r_cal.csv', 'sample_g_cal.csv', 'sample_b_cal.csv']
elif ((not is_calibrated) and is_rgb):
filenames = ['sample_r.csv', 'sample_g.csv', 'sample_b.csv']
elif (is_calibrated and (not is_rgb)):
filenames = ['sample_Ll_cal.csv', 'sample_La_cal.csv', 'sample_Lb_cal.csv']
else:
filenames = ['sample_Ll.csv', 'sample_La.csv', 'sample_Lb.csv']
os.chdir(folder)
self.compositions = compositions
compositions = pd.Series(compositions)
self.red = pd.read_csv(filenames[0], header=None)
self.red = self.red.T
self.red.columns = compositions
self.green = pd.read_csv(filenames[1], header=None)
self.green = self.green.T
self.green.columns = compositions
self.blue = pd.read_csv(filenames[2], header=None)
self.blue = self.blue.T
self.blue.columns = compositions
self.time = pd.read_csv('times.csv', header=None)
if cutoff:
self.time = self.time[self.time[0] < cutoff]
self.red = self.red.iloc[:self.time.shape[0],:]
self.blue = self.blue.iloc[:self.time.shape[0],:]
self.green = self.green.iloc[:self.time.shape[0],:]
def preprocess(self, normalize = None):
time_col = pd.DataFrame(pd.np.tile(self.time.values, (self.red.shape[1], 1)))
red = self.red.melt(var_name='columns')
green = self.green.melt(var_name='columns')
blue = self.blue.melt(var_name='columns')
red['time'] = time_col
green['time'] = time_col
blue['time'] = time_col
min_color = np.min([red['value'].min(), green['value'].min(), blue['value'].min()])
max_color = np.max([red['value'].max(), green['value'].max(), blue['value'].max()])
if normalize == 'max':
red['value'] = red['value'] / max_color
green['value'] = green['value'] / max_color
blue['value'] = blue['value'] / max_color
elif normalize == 'min_max':
red['value'] = (red['value'] - min_color) / (max_color - min_color)
green['value'] = (green['value'] - min_color) / (max_color - min_color)
blue['value'] = (blue['value'] - min_color) / (max_color - min_color)
self.red_p = red
self.blue_p = blue
self.green_p = green
return red, green, blue, time_col
def plot_samples(self, color_name):
dfm = pd.DataFrame()
sns.set_style("darkgrid")
if color_name == 'red':
dfm = self.red_p
g = sns.FacetGrid(dfm, col='columns', col_wrap=4)
g = (g.map(sns.lineplot, 'time','value'))
elif color_name == 'green':
dfm = self.green_p
g = sns.FacetGrid(dfm, col='columns', col_wrap=4)
g = (g.map(sns.lineplot, 'time','value'))
elif color_name == 'blue':
dfm = self.blue_p
g = sns.FacetGrid(dfm, col='columns', col_wrap=4)
g = (g.map(sns.lineplot, 'time','value'))
elif color_name == 'all':
red_t = self.red_p
red_t['Color'] = 'Red'
blue_t = self.blue_p
blue_t['Color'] = 'Blue'
green_t = self.green_p
green_t['Color'] = 'Green'
dfm = pd.concat([red_t,blue_t,green_t])
sns.set_palette(palette=sns.xkcd_palette(["pale red", "denim blue", "medium green"]))
g = sns.FacetGrid(dfm, col='columns', hue='Color', col_wrap=4)
#Define axis limits here
g.set(ylim=(0, 140))
g = (g.map(sns.lineplot, 'time', 'value'))
def compute_degradation(self, method):
merits_r = []
merits_g = []
merits_b = []
for key, value in self.compositions.items():
filtered_r = self.red_p[self.red_p['columns'] == value]
filtered_g = self.green_p[self.green_p['columns'] == value]
filtered_b = self.blue_p[self.blue_p['columns'] == value]
#Only using area under curve
if method == 'area':
merit_r = simps(filtered_r.value, filtered_r.time)
merit_g = simps(filtered_g.value, filtered_g.time)
merit_b = simps(filtered_b.value, filtered_b.time)
#Using differential area between curves, always positive and robust to multiple intersections
elif method == 'diff_area':
merit_r = simps( abs(filtered_r.value - np.repeat(filtered_r.value.iloc[0],len(filtered_r.value))),
filtered_r.time)
merit_g = simps( abs(filtered_g.value - np.repeat(filtered_g.value.iloc[0],len(filtered_g.value))),
filtered_g.time)
merit_b = simps( abs(filtered_b.value - np.repeat(filtered_b.value.iloc[0],len(filtered_b.value))),
filtered_b.time)
elif method == 'dtw':
exp_r = np.zeros((len(filtered_r.value), 2))
base_r = np.zeros((len(filtered_r.value), 2))
base_r[:,0] = filtered_r.time
base_r[:,1] = np.repeat(filtered_r.value.iloc[0],len(filtered_r.value))
exp_r[:, 0] = filtered_r.time
exp_r[:, 1] = filtered_r.value
merit_r, rr = similaritymeasures.dtw(exp_r, base_r)
exp_g = np.zeros((len(filtered_g.value), 2))
base_g = np.zeros((len(filtered_g.value), 2))
base_g[:,0] = filtered_g.time
base_g[:,1] = np.repeat(filtered_g.value.iloc[0],len(filtered_g.value))
exp_g[:, 0] = filtered_g.time
exp_g[:, 1] = filtered_g.value
merit_g, gr = similaritymeasures.dtw(exp_g, base_g)
exp_b = np.zeros((len(filtered_b.value), 2))
base_b = np.zeros((len(filtered_b.value), 2))
base_b[:,0] = filtered_b.time
base_b[:,1] = np.repeat(filtered_b.value.iloc[0],len(filtered_b.value))
exp_b[:, 0] = filtered_b.time
exp_b[:, 1] = filtered_b.value
merit_b, br = similaritymeasures.dtw(exp_b, base_b)
#Inverted momentum, scaled by 1/sqrt(x) changing the scaling changes the importance of our sample in time... we
#can compute a rate of degradation based in that
elif method == 'inverted_moment':
c = 1 #Avoids numerical errors during evaluation
merit_r = simps(filtered_r.value * (1/np.sqrt(filtered_r.time + c)), filtered_r.time)
merit_g = simps(filtered_g.value * (1/np.sqrt(filtered_g.time + c)), filtered_g.time)
merit_b = simps(filtered_b.value * (1/np.sqrt(filtered_b.time + c)), filtered_b.time)
merit_r = simps( abs( (1/np.sqrt(filtered_r.time + c))*(filtered_r.value - np.repeat(filtered_r.value.iloc[0],len(filtered_r.value)))),
filtered_r.time )
merit_g = simps( abs((1/np.sqrt(filtered_g.time + c))*(filtered_g.value - np.repeat(filtered_g.value.iloc[0],len(filtered_g.value)))),
filtered_g.time )
merit_b = simps( abs((1/np.sqrt(filtered_b.time + c))*(filtered_b.value - np.repeat(filtered_b.value.iloc[0],len(filtered_b.value)))),
filtered_b.time )
merits_r.append(merit_r)
merits_g.append(merit_g)
merits_b.append(merit_b)
degradation_df = pd.DataFrame(
{'Red': merits_r,
'Green': merits_g,
'Blue': merits_b,
})
degradation_df['Merit'] = degradation_df.Red + degradation_df.Blue + degradation_df.Green
#degradation_df.index = pd.Series(self.compositions)
degradation_df.insert(loc=0, column='Sample', value=pd.Series(self.compositions))
return degradation_df