Skip to content

Commit 0734561

Browse files
committed
Add Focus and BandPower data processing in background
1 parent 8efcad5 commit 0734561

3 files changed

Lines changed: 205 additions & 191 deletions

File tree

OpenBCI_GUI/DataProcessing.pde

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,12 @@ class DataProcessing {
296296
}
297297
}
298298

299-
//Compute EMG values independent of widgets
299+
/////////////////////////////////////////////////////////////
300+
// Compute widget values independent of widgets being open //
301+
// -RW #1094 //
302+
/////////////////////////////////////////////////////////////
300303
emgSettings.values.process(dataProcessingFilteredBuffer);
304+
w_focus.updateFocusWidgetData();
305+
w_bandPower.updateBandPowerWidgetData();
301306
}
302307
}

OpenBCI_GUI/W_BandPower.pde

Lines changed: 193 additions & 188 deletions
Original file line numberDiff line numberDiff line change
@@ -1,188 +1,193 @@
1-
2-
////////////////////////////////////////////////////////////////////////////////////////////////////////
3-
//
4-
// W_BandPowers.pde
5-
//
6-
// This is a band power visualization widget!
7-
// (Couldn't think up more)
8-
// This is for visualizing the power of each brainwave band: delta, theta, alpha, beta, gamma
9-
// Averaged over all channels
10-
//
11-
// Created by: Wangshu Sun, May 2017
12-
// Modified by: Richard Waltman, March 2022
13-
//
14-
////////////////////////////////////////////////////////////////////////////////////////////////////////
15-
16-
17-
18-
class W_BandPower extends Widget {
19-
20-
// indexes
21-
final int DELTA = 0; // 1-4 Hz
22-
final int THETA = 1; // 4-8 Hz
23-
final int ALPHA = 2; // 8-13 Hz
24-
final int BETA = 3; // 13-30 Hz
25-
final int GAMMA = 4; // 30-55 Hz
26-
27-
private final int NUM_BANDS = 5;
28-
private float[] activePower = new float[NUM_BANDS];
29-
private float[] normalizedBandPowers = new float[NUM_BANDS];
30-
31-
GPlot bp_plot;
32-
public ChannelSelect bpChanSelect;
33-
boolean prevChanSelectIsVisible = false;
34-
35-
List<controlP5.Controller> cp5ElementsToCheck = new ArrayList<controlP5.Controller>();
36-
37-
W_BandPower(PApplet _parent) {
38-
super(_parent); //calls the parent CONSTRUCTOR method of Widget (DON'T REMOVE)
39-
40-
//Add channel select dropdown to this widget
41-
bpChanSelect = new ChannelSelect(pApplet, this, x, y, w, navH, "BP_Channels");
42-
bpChanSelect.activateAllButtons();
43-
cp5ElementsToCheck.addAll(bpChanSelect.getCp5ElementsForOverlapCheck());
44-
45-
//Add settings dropdowns
46-
addDropdown("Smoothing", "Smooth", Arrays.asList(settings.fftSmoothingArray), smoothFac_ind); //smoothFac_ind is a global variable at the top of W_HeadPlot.pde
47-
addDropdown("UnfiltFilt", "Filters?", Arrays.asList(settings.fftFilterArray), settings.fftFilterSave);
48-
49-
// Setup for the BandPower plot
50-
bp_plot = new GPlot(_parent, x, y-navHeight, w, h+navHeight);
51-
// bp_plot.setPos(x, y+navHeight);
52-
bp_plot.setDim(w, h);
53-
bp_plot.setLogScale("y");
54-
bp_plot.setYLim(0.1, 100);
55-
bp_plot.setXLim(0, 5);
56-
bp_plot.getYAxis().setNTicks(9);
57-
bp_plot.getXAxis().setNTicks(0);
58-
bp_plot.getTitle().setTextAlignment(LEFT);
59-
bp_plot.getTitle().setRelativePos(0);
60-
bp_plot.setAllFontProperties("Arial", 0, 14);
61-
bp_plot.getYAxis().getAxisLabel().setText("Power — (uV)^2 / Hz");
62-
bp_plot.getXAxis().setAxisLabelText("EEG Power Bands");
63-
bp_plot.getXAxis().getAxisLabel().setOffset(42f);
64-
bp_plot.startHistograms(GPlot.VERTICAL);
65-
bp_plot.getHistogram().setDrawLabels(true);
66-
bp_plot.getXAxis().setFontColor(OPENBCI_DARKBLUE);
67-
bp_plot.getXAxis().setLineColor(OPENBCI_DARKBLUE);
68-
bp_plot.getXAxis().getAxisLabel().setFontColor(OPENBCI_DARKBLUE);
69-
bp_plot.getYAxis().setFontColor(OPENBCI_DARKBLUE);
70-
bp_plot.getYAxis().setLineColor(OPENBCI_DARKBLUE);
71-
bp_plot.getYAxis().getAxisLabel().setFontColor(OPENBCI_DARKBLUE);
72-
73-
//setting border of histograms to match BG
74-
bp_plot.getHistogram().setLineColors(new color[]{
75-
color(245), color(245), color(245), color(245), color(245)
76-
}
77-
);
78-
//setting bg colors of histogram bars to match the color scheme of the channel colors w/ an opacity of 150/255
79-
bp_plot.getHistogram().setBgColors(new color[] {
80-
color((int)channelColors[6], 200),
81-
color((int)channelColors[4], 200),
82-
color((int)channelColors[3], 200),
83-
color((int)channelColors[2], 200),
84-
color((int)channelColors[1], 200),
85-
}
86-
);
87-
//setting color of text label for each histogram bar on the x axis
88-
bp_plot.getHistogram().setFontColor(OPENBCI_DARKBLUE);
89-
} //end of constructor
90-
91-
void update() {
92-
super.update(); //calls the parent update() method of Widget (DON'T REMOVE)
93-
94-
float normalizingSum = 0;
95-
96-
for (int i = 0; i < NUM_BANDS; i++) {
97-
float sum = 0;
98-
99-
for (int j = 0; j < bpChanSelect.activeChan.size(); j++) {
100-
int chan = bpChanSelect.activeChan.get(j);
101-
sum += dataProcessing.avgPowerInBins[chan][i];
102-
}
103-
104-
activePower[i] = sum / bpChanSelect.activeChan.size();
105-
106-
normalizingSum += activePower[i];
107-
}
108-
109-
for (int i = 0; i < NUM_BANDS; i++) {
110-
normalizedBandPowers[i] = activePower[i] / normalizingSum;
111-
}
112-
113-
//Update channel checkboxes and active channels
114-
bpChanSelect.update(x, y, w);
115-
116-
//Flex the Gplot graph when channel select dropdown is open/closed
117-
if (bpChanSelect.isVisible() != prevChanSelectIsVisible) {
118-
flexGPlotSizeAndPosition();
119-
prevChanSelectIsVisible = bpChanSelect.isVisible();
120-
}
121-
122-
GPointsArray bp_points = new GPointsArray(dataProcessing.headWidePower.length);
123-
bp_points.add(DELTA + 0.5, activePower[DELTA], "DELTA\n0.5-4Hz");
124-
bp_points.add(THETA + 0.5, activePower[THETA], "THETA\n4-8Hz");
125-
bp_points.add(ALPHA + 0.5, activePower[ALPHA], "ALPHA\n8-13Hz");
126-
bp_points.add(BETA + 0.5, activePower[BETA], "BETA\n13-32Hz");
127-
bp_points.add(GAMMA + 0.5, activePower[GAMMA], "GAMMA\n32-100Hz");
128-
bp_plot.setPoints(bp_points);
129-
130-
if (bpChanSelect.isVisible()) {
131-
lockElementsOnOverlapCheck(cp5ElementsToCheck);
132-
}
133-
} //end of update
134-
135-
void draw() {
136-
super.draw(); //calls the parent draw() method of Widget (DON'T REMOVE)
137-
pushStyle();
138-
139-
//remember to refer to x,y,w,h which are the positioning variables of the Widget class
140-
// Draw the third plot
141-
bp_plot.beginDraw();
142-
bp_plot.drawBackground();
143-
bp_plot.drawBox();
144-
bp_plot.drawXAxis();
145-
bp_plot.drawYAxis();
146-
bp_plot.drawGridLines(GPlot.HORIZONTAL);
147-
bp_plot.drawHistograms();
148-
bp_plot.endDraw();
149-
150-
//for this widget need to redraw the grey bar, bc the FFT plot covers it up...
151-
fill(200, 200, 200);
152-
rect(x, y - navHeight, w, navHeight); //button bar
153-
154-
popStyle();
155-
bpChanSelect.draw();
156-
}
157-
158-
void screenResized() {
159-
super.screenResized(); //calls the parent screenResized() method of Widget (DON'T REMOVE)
160-
161-
flexGPlotSizeAndPosition();
162-
163-
bpChanSelect.screenResized(pApplet);
164-
}
165-
166-
void mousePressed() {
167-
super.mousePressed(); //calls the parent mousePressed() method of Widget (DON'T REMOVE)
168-
bpChanSelect.mousePressed(this.dropdownIsActive); //Calls channel select mousePressed and checks if clicked
169-
}
170-
171-
void mouseReleased() {
172-
super.mouseReleased(); //calls the parent mouseReleased() method of Widget (DON'T REMOVE)
173-
}
174-
175-
void flexGPlotSizeAndPosition() {
176-
if (bpChanSelect.isVisible()) {
177-
bp_plot.setPos(x, y + bpChanSelect.getHeight() - navH);
178-
bp_plot.setOuterDim(w, h - bpChanSelect.getHeight() + navH);
179-
} else {
180-
bp_plot.setPos(x, y - navH);
181-
bp_plot.setOuterDim(w, h + navH);
182-
}
183-
}
184-
185-
public float[] getNormalizedBPSelectedChannels() {
186-
return normalizedBandPowers;
187-
}
188-
};
1+
2+
////////////////////////////////////////////////////////////////////////////////////////////////////////
3+
//
4+
// W_BandPowers.pde
5+
//
6+
// This is a band power visualization widget!
7+
// (Couldn't think up more)
8+
// This is for visualizing the power of each brainwave band: delta, theta, alpha, beta, gamma
9+
// Averaged over all channels
10+
//
11+
// Created by: Wangshu Sun, May 2017
12+
// Modified by: Richard Waltman, March 2022
13+
//
14+
////////////////////////////////////////////////////////////////////////////////////////////////////////
15+
16+
17+
18+
class W_BandPower extends Widget {
19+
20+
// indexes
21+
private final int DELTA = 0; // 1-4 Hz
22+
private final int THETA = 1; // 4-8 Hz
23+
private final int ALPHA = 2; // 8-13 Hz
24+
private final int BETA = 3; // 13-30 Hz
25+
private final int GAMMA = 4; // 30-55 Hz
26+
27+
private final int NUM_BANDS = 5;
28+
private float[] activePower = new float[NUM_BANDS];
29+
private float[] normalizedBandPowers = new float[NUM_BANDS];
30+
31+
private GPlot bp_plot;
32+
public ChannelSelect bpChanSelect;
33+
private boolean prevChanSelectIsVisible = false;
34+
35+
private List<controlP5.Controller> cp5ElementsToCheck = new ArrayList<controlP5.Controller>();
36+
37+
W_BandPower(PApplet _parent) {
38+
super(_parent); //calls the parent CONSTRUCTOR method of Widget (DON'T REMOVE)
39+
40+
//Add channel select dropdown to this widget
41+
bpChanSelect = new ChannelSelect(pApplet, this, x, y, w, navH, "BP_Channels");
42+
bpChanSelect.activateAllButtons();
43+
cp5ElementsToCheck.addAll(bpChanSelect.getCp5ElementsForOverlapCheck());
44+
45+
//Add settings dropdowns
46+
addDropdown("Smoothing", "Smooth", Arrays.asList(settings.fftSmoothingArray), smoothFac_ind); //smoothFac_ind is a global variable at the top of W_HeadPlot.pde
47+
addDropdown("UnfiltFilt", "Filters?", Arrays.asList(settings.fftFilterArray), settings.fftFilterSave);
48+
49+
// Setup for the BandPower plot
50+
bp_plot = new GPlot(_parent, x, y-navHeight, w, h+navHeight);
51+
// bp_plot.setPos(x, y+navHeight);
52+
bp_plot.setDim(w, h);
53+
bp_plot.setLogScale("y");
54+
bp_plot.setYLim(0.1, 100);
55+
bp_plot.setXLim(0, 5);
56+
bp_plot.getYAxis().setNTicks(9);
57+
bp_plot.getXAxis().setNTicks(0);
58+
bp_plot.getTitle().setTextAlignment(LEFT);
59+
bp_plot.getTitle().setRelativePos(0);
60+
bp_plot.setAllFontProperties("Arial", 0, 14);
61+
bp_plot.getYAxis().getAxisLabel().setText("Power — (uV)^2 / Hz");
62+
bp_plot.getXAxis().setAxisLabelText("EEG Power Bands");
63+
bp_plot.getXAxis().getAxisLabel().setOffset(42f);
64+
bp_plot.startHistograms(GPlot.VERTICAL);
65+
bp_plot.getHistogram().setDrawLabels(true);
66+
bp_plot.getXAxis().setFontColor(OPENBCI_DARKBLUE);
67+
bp_plot.getXAxis().setLineColor(OPENBCI_DARKBLUE);
68+
bp_plot.getXAxis().getAxisLabel().setFontColor(OPENBCI_DARKBLUE);
69+
bp_plot.getYAxis().setFontColor(OPENBCI_DARKBLUE);
70+
bp_plot.getYAxis().setLineColor(OPENBCI_DARKBLUE);
71+
bp_plot.getYAxis().getAxisLabel().setFontColor(OPENBCI_DARKBLUE);
72+
73+
//setting border of histograms to match BG
74+
bp_plot.getHistogram().setLineColors(new color[]{
75+
color(245), color(245), color(245), color(245), color(245)
76+
}
77+
);
78+
//setting bg colors of histogram bars to match the color scheme of the channel colors w/ an opacity of 150/255
79+
bp_plot.getHistogram().setBgColors(new color[] {
80+
color((int)channelColors[6], 200),
81+
color((int)channelColors[4], 200),
82+
color((int)channelColors[3], 200),
83+
color((int)channelColors[2], 200),
84+
color((int)channelColors[1], 200),
85+
}
86+
);
87+
//setting color of text label for each histogram bar on the x axis
88+
bp_plot.getHistogram().setFontColor(OPENBCI_DARKBLUE);
89+
} //end of constructor
90+
91+
public void update() {
92+
super.update(); //calls the parent update() method of Widget (DON'T REMOVE)
93+
94+
95+
96+
//Update channel checkboxes and active channels
97+
bpChanSelect.update(x, y, w);
98+
99+
//Flex the Gplot graph when channel select dropdown is open/closed
100+
if (bpChanSelect.isVisible() != prevChanSelectIsVisible) {
101+
flexGPlotSizeAndPosition();
102+
prevChanSelectIsVisible = bpChanSelect.isVisible();
103+
}
104+
105+
GPointsArray bp_points = new GPointsArray(dataProcessing.headWidePower.length);
106+
bp_points.add(DELTA + 0.5, activePower[DELTA], "DELTA\n0.5-4Hz");
107+
bp_points.add(THETA + 0.5, activePower[THETA], "THETA\n4-8Hz");
108+
bp_points.add(ALPHA + 0.5, activePower[ALPHA], "ALPHA\n8-13Hz");
109+
bp_points.add(BETA + 0.5, activePower[BETA], "BETA\n13-32Hz");
110+
bp_points.add(GAMMA + 0.5, activePower[GAMMA], "GAMMA\n32-100Hz");
111+
bp_plot.setPoints(bp_points);
112+
113+
if (bpChanSelect.isVisible()) {
114+
lockElementsOnOverlapCheck(cp5ElementsToCheck);
115+
}
116+
} //end of update
117+
118+
public void draw() {
119+
super.draw(); //calls the parent draw() method of Widget (DON'T REMOVE)
120+
pushStyle();
121+
122+
//remember to refer to x,y,w,h which are the positioning variables of the Widget class
123+
// Draw the third plot
124+
bp_plot.beginDraw();
125+
bp_plot.drawBackground();
126+
bp_plot.drawBox();
127+
bp_plot.drawXAxis();
128+
bp_plot.drawYAxis();
129+
bp_plot.drawGridLines(GPlot.HORIZONTAL);
130+
bp_plot.drawHistograms();
131+
bp_plot.endDraw();
132+
133+
//for this widget need to redraw the grey bar, bc the FFT plot covers it up...
134+
fill(200, 200, 200);
135+
rect(x, y - navHeight, w, navHeight); //button bar
136+
137+
popStyle();
138+
bpChanSelect.draw();
139+
}
140+
141+
public void screenResized() {
142+
super.screenResized(); //calls the parent screenResized() method of Widget (DON'T REMOVE)
143+
144+
flexGPlotSizeAndPosition();
145+
146+
bpChanSelect.screenResized(pApplet);
147+
}
148+
149+
public void mousePressed() {
150+
super.mousePressed(); //calls the parent mousePressed() method of Widget (DON'T REMOVE)
151+
bpChanSelect.mousePressed(this.dropdownIsActive); //Calls channel select mousePressed and checks if clicked
152+
}
153+
154+
public void mouseReleased() {
155+
super.mouseReleased(); //calls the parent mouseReleased() method of Widget (DON'T REMOVE)
156+
}
157+
158+
void flexGPlotSizeAndPosition() {
159+
if (bpChanSelect.isVisible()) {
160+
bp_plot.setPos(x, y + bpChanSelect.getHeight() - navH);
161+
bp_plot.setOuterDim(w, h - bpChanSelect.getHeight() + navH);
162+
} else {
163+
bp_plot.setPos(x, y - navH);
164+
bp_plot.setOuterDim(w, h + navH);
165+
}
166+
}
167+
168+
public float[] getNormalizedBPSelectedChannels() {
169+
return normalizedBandPowers;
170+
}
171+
172+
//Called in DataProcessing.pde to update data even if widget is closed
173+
public void updateBandPowerWidgetData() {
174+
float normalizingSum = 0;
175+
176+
for (int i = 0; i < NUM_BANDS; i++) {
177+
float sum = 0;
178+
179+
for (int j = 0; j < bpChanSelect.activeChan.size(); j++) {
180+
int chan = bpChanSelect.activeChan.get(j);
181+
sum += dataProcessing.avgPowerInBins[chan][i];
182+
}
183+
184+
activePower[i] = sum / bpChanSelect.activeChan.size();
185+
186+
normalizingSum += activePower[i];
187+
}
188+
189+
for (int i = 0; i < NUM_BANDS; i++) {
190+
normalizedBandPowers[i] = activePower[i] / normalizingSum;
191+
}
192+
}
193+
};

0 commit comments

Comments
 (0)