Skip to content

Commit 5a86930

Browse files
author
Marian Dovgialo
committed
Merge branch 'development-fuw' into 'development'
#13 Development fuw See merge request brain/svarog2!207
2 parents 2fe1e9f + b593fd2 commit 5a86930

File tree

47 files changed

+658
-116
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+658
-116
lines changed

svarog/src/main/java/org/signalml/app/config/ApplicationConfiguration.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ public class ApplicationConfiguration extends AbstractXMLConfiguration implement
9595

9696
private String openbciIPAddress;
9797
private int openbciPort;
98+
private boolean scrollingMode;
9899
private String sentryDsn;
99100
private String sentrySite;
100101
private boolean sendSentryTelemetry;
@@ -601,6 +602,14 @@ public void setOpenbciPort(int openbciPort) {
601602
this.openbciPort = openbciPort;
602603
}
603604

605+
public boolean isScrollingMode() {
606+
return scrollingMode;
607+
}
608+
609+
public void setScrollingMode(boolean scrollingMode) {
610+
this.scrollingMode = scrollingMode;
611+
}
612+
604613
public String getSentryDsn() {
605614
return sentryDsn;
606615
}

svarog/src/main/java/org/signalml/app/config/ConfigurationDefaults.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ public static void setApplicationConfigurationDefaults(ApplicationConfiguration
138138
config.setMonitorPageSize(getFloat("monitor.pageSize"));
139139
config.setOpenbciIPAddress(getString("monitor.openbciIPAddress"));
140140
config.setOpenbciPort(getInt("monitor.openbciPort"));
141+
config.setScrollingMode(getBoolean("monitor.scrollingMode"));
141142
}
142143

143144
public static void setZoomSignalSettingsDefaults(ZoomSignalSettings settings) {

svarog/src/main/java/org/signalml/app/document/MonitorSignalDocument.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -177,8 +177,7 @@ public void openDocument() throws SignalMLException, IOException {
177177
}
178178

179179
logger.info("Start initializing monitor data.");
180-
tagSet = new StyledMonitorTagSet(descriptor.getSignalParameters().getPageSize(), 5,
181-
descriptor.getSignalParameters().getSamplingFrequency());
180+
tagSet = new StyledMonitorTagSet(descriptor.getSignalParameters().getPageSize(), 5);
182181
if (descriptor.getTagStyles() != null) {
183182
tagSet.copyStylesFrom(descriptor.getTagStyles());
184183
}

svarog/src/main/java/org/signalml/app/document/signal/AsciiSignalSampleSource.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ protected BaseSignalSampleSource duplicateInternal() throws IOException {
4545
}
4646

4747
@Override
48-
public synchronized void getSamples(int channel, double[] target, int signalOffset, int count, int arrayOffset) {
48+
public synchronized long getSamples(int channel, double[] target, int signalOffset, int count, int arrayOffset) {
4949
int channelCount = getChannelCount();
5050
if (channel < 0 || channel >= channelCount) {
5151
throw new IndexOutOfBoundsException("Bad channel number [" + channel + "]");
@@ -86,6 +86,7 @@ public synchronized void getSamples(int channel, double[] target, int signalOffs
8686
parsingErrorDialogShown = true;
8787
Dialogs.showError(_("CSV file is badly formatted. Some data may not be displayed properly."));
8888
}
89+
return 0;
8990
}
9091

9192
}

svarog/src/main/java/org/signalml/app/view/preferences/MonitorConfigPanel.java

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import javax.swing.BoxLayout;
66
import javax.swing.GroupLayout;
77
import javax.swing.GroupLayout.Alignment;
8+
import javax.swing.JCheckBox;
89
import javax.swing.JLabel;
910
import javax.swing.JPanel;
1011
import javax.swing.JSpinner.NumberEditor;
@@ -28,6 +29,7 @@ public class MonitorConfigPanel extends AbstractPanel {
2829
*/
2930
private JTextField openbciIpAddressTextField;
3031
private IntegerSpinner openbciPortSpinner;
32+
private JCheckBox scrollingModeCheckBox;
3133

3234
/**
3335
* Default constructor.
@@ -61,7 +63,7 @@ protected JPanel createOpenbciAddressPanel() {
6163

6264
hGroup.addGroup(layout.createParallelGroup().addComponent(openbciIpAddressLabel).addComponent(openbciPortLabel));
6365

64-
hGroup.addGroup(layout.createParallelGroup().addComponent(getOpenbciIpAddressTextField()).addComponent(getOpenbciPortSpinner()));
66+
hGroup.addGroup(layout.createParallelGroup().addComponent(getOpenbciIpAddressTextField()).addComponent(getOpenbciPortSpinner()).addComponent(getScrollingModeCheckBox()));
6567

6668
layout.setHorizontalGroup(hGroup);
6769

@@ -71,6 +73,8 @@ protected JPanel createOpenbciAddressPanel() {
7173

7274
vGroup.addGroup(layout.createParallelGroup(Alignment.BASELINE).addComponent(openbciPortLabel).addComponent(getOpenbciPortSpinner()));
7375

76+
vGroup.addGroup(layout.createParallelGroup(Alignment.BASELINE).addComponent(getScrollingModeCheckBox()));
77+
7478
layout.setVerticalGroup(vGroup);
7579

7680
return openbciAddressPanel;
@@ -92,6 +96,13 @@ protected IntegerSpinner getOpenbciPortSpinner() {
9296
return openbciPortSpinner;
9397
}
9498

99+
protected JCheckBox getScrollingModeCheckBox() {
100+
if (scrollingModeCheckBox == null) {
101+
scrollingModeCheckBox = new JCheckBox("View in scrolling mode (change will not affect any currently open signals)");
102+
}
103+
return scrollingModeCheckBox;
104+
}
105+
95106
/**
96107
* Fills all the fields of this panel from the given
97108
* {@link ApplicationConfiguration configuration} of Svarog.
@@ -102,6 +113,7 @@ protected IntegerSpinner getOpenbciPortSpinner() {
102113
public void fillPanelFromModel(ApplicationConfiguration applicationConfig) {
103114
getOpenbciIpAddressTextField().setText(applicationConfig.getOpenbciIPAddress());
104115
getOpenbciPortSpinner().setValue(applicationConfig.getOpenbciPort());
116+
getScrollingModeCheckBox().setSelected(applicationConfig.isScrollingMode());
105117
}
106118

107119
/**
@@ -113,7 +125,8 @@ public void fillPanelFromModel(ApplicationConfiguration applicationConfig) {
113125
*/
114126
public void fillModelFromPanel(ApplicationConfiguration applicationConfig) {
115127
applicationConfig.setOpenbciIPAddress(getOpenbciIpAddressTextField().getText());
116-
applicationConfig.setOpenbciPort(openbciPortSpinner.getValue());
128+
applicationConfig.setOpenbciPort(getOpenbciPortSpinner().getValue());
129+
applicationConfig.setScrollingMode(getScrollingModeCheckBox().isSelected());
117130
}
118131

119132
/**
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package org.signalml.app.view.signal;
2+
3+
/**
4+
* Simple data structure with tag's position (start) and
5+
* a number of epoch in which it has been created.
6+
* Used internally in StaticRenderingHelper.
7+
*/
8+
class InitialTagTiming {
9+
10+
public final double position;
11+
12+
public final long cycleNumber;
13+
14+
InitialTagTiming(double position, long cycleNumber) {
15+
this.position = position;
16+
this.cycleNumber = cycleNumber;
17+
}
18+
}

svarog/src/main/java/org/signalml/app/view/signal/SignalPlot.java

Lines changed: 58 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858
import org.signalml.domain.signal.raw.RawSignalSampleSource;
5959
import org.signalml.domain.signal.samplesource.MultichannelSampleSource;
6060
import org.signalml.domain.signal.samplesource.OriginalMultichannelSampleSource;
61+
import org.signalml.domain.tag.MonitorTag;
6162
import org.signalml.domain.tag.StyledTagSet;
6263
import org.signalml.domain.tag.TagDifference;
6364
import org.signalml.domain.tag.TagDifferenceSet;
@@ -179,6 +180,9 @@ public class SignalPlot extends JComponent implements PropertyChangeListener, Ch
179180
private int horizontalPixelLead;
180181
private int verticalPixelLead;
181182

183+
/** used for static (non-scrolling) rendering of on-line signal tags */
184+
private final StaticRenderingHelper staticRendering;
185+
182186
private boolean compensationEnabled = true;
183187
private boolean ignoreSliderEvents = false;
184188

@@ -214,8 +218,9 @@ public SignalPlot(SignalDocument document, SignalView view, SignalPlot masterPlo
214218
setBackground(Color.WHITE);
215219
setFocusable(true);
216220

217-
if (document.getSampleSource() instanceof RawSignalSampleSource) {
218-
double timestamp = ((RawSignalSampleSource) document.getSampleSource()).getFirstSampleTimestamp();
221+
OriginalMultichannelSampleSource sampleSource = document.getSampleSource();
222+
if (sampleSource instanceof RawSignalSampleSource) {
223+
double timestamp = ((RawSignalSampleSource) sampleSource).getFirstSampleTimestamp();
219224
firstSampleTimestamp = Math.round(timestamp);
220225
} else {
221226
firstSampleTimestamp = 0;
@@ -328,8 +333,15 @@ private void maybeShowPopupMenu(MouseEvent e) {
328333

329334
});
330335
if (document instanceof MonitorSignalDocument) {
336+
if (!config.isScrollingMode()) {
337+
staticRendering = new StaticRenderingHelper(sampleSource.getChannelCount(), sampleSource.getSampleCount(0), sampleSource.getSamplingFrequency());
338+
} else {
339+
staticRendering = null;
340+
}
331341
//for online signals renderrer should know that it's online
332342
renderer.setOnline(true);
343+
} else {
344+
staticRendering = null;
333345
}
334346

335347
}
@@ -832,6 +844,16 @@ protected void paintComponent(Graphics gOrig) {
832844
int clipEndX = clip.x + clip.width - 1;
833845
int clipEndY = clip.y + clip.height - 1;
834846

847+
if (staticRendering != null) try {
848+
// pre-fetching data and updating rendering state
849+
// to avoid mismatch between signal and tags
850+
staticRendering.fetchSamples(signalChain);
851+
} catch (RuntimeException ex) {
852+
logger.error("failed to read samples in static rendering mode", ex);
853+
setVisible(false);
854+
throw ex;
855+
}
856+
835857
prepareToPaintTags();
836858

837859
PositionedTag tagSelection = view.getTagSelection(this);
@@ -918,10 +940,8 @@ protected void paintComponent(Graphics gOrig) {
918940
}
919941

920942
visibleCount = 0;
921-
channel = startChannel;
922-
while (visibleCount < maxNumberOfChannels && channel < channelCount) {
943+
for (channel=startChannel; visibleCount < maxNumberOfChannels && channel < channelCount; ++channel) {
923944
if (!isChannelVisible(channel)) {
924-
channel++;
925945
continue;
926946
}
927947
visibleCount++;
@@ -938,8 +958,12 @@ protected void paintComponent(Graphics gOrig) {
938958
}
939959

940960
try {
941-
942-
signalChain.getSamples(channel, samples, firstSample, length, 0);
961+
if (staticRendering != null) {
962+
int samplesMargin = (int) (10 / timeZoomFactor); // 10 pixels
963+
staticRendering.getSamples(samplesMargin, channel, samples, firstSample, length);
964+
} else {
965+
signalChain.getSamples(channel, samples, firstSample, length, 0);
966+
}
943967
} catch (RuntimeException ex) {
944968
logger.error(format("failed to read %d samples starting at %d, till %d, channel %d",
945969
length, firstSample, lastSample, sampleCount[channel]));
@@ -954,8 +978,6 @@ protected void paintComponent(Graphics gOrig) {
954978
channelLevel[channel], timeZoomFactor, pixelPerValueForChannel,
955979
clamped ? clampLimit : null, dcOffsetRemoved
956980
);
957-
958-
channel++;
959981
}
960982

961983
if (signalXOR) {
@@ -1472,14 +1494,23 @@ public int toChannelSpace(Point p) {
14721494
return channel + numberOfInvisibleChannels;
14731495
}
14741496

1497+
TagTiming computeTagTiming(SignalSelection tag) {
1498+
if (staticRendering != null && (tag instanceof MonitorTag)) {
1499+
return staticRendering.computeTagTiming((MonitorTag) tag);
1500+
} else {
1501+
return new TagTiming(tag.getPosition(), tag.getLength());
1502+
}
1503+
}
1504+
14751505
public Rectangle getPixelSelectionBounds(SignalSelection selection, Rectangle useRect) {
14761506

1477-
double position = selection.getPosition();
1478-
double length = selection.getLength();
1507+
TagTiming timing = computeTagTiming(selection);
1508+
final double position = timing.position;
1509+
final double length = timing.length;
14791510
SignalSelectionType type = selection.getType();
14801511

1481-
int selLeft = (int) Math.floor(selection.getPosition() * pixelPerSecond);
1482-
int selRight = (int) Math.ceil(selection.getLength() * pixelPerSecond);
1512+
int selLeft = (int) Math.floor(position * pixelPerSecond);
1513+
int selRight = (int) Math.ceil((position + length) * pixelPerSecond);
14831514
int selTop;
14841515
int selBottom;
14851516

@@ -1528,7 +1559,7 @@ public Rectangle getPixelBlockTagBounds(SignalSelection tag, boolean marker, int
15281559
Rectangle rect = getTagSelectionRectangle(tag, marker, tagCnt, useRect);
15291560

15301561
if (rect.x > 0 && blockLinesVisible && pixelPerBlock > 4) {
1531-
int linePosition = (int) ((int) ((tag.getPosition() / blockSize)) * pixelPerBlock);
1562+
int linePosition = (int) ((int) ((computeTagTiming(tag).position / blockSize)) * pixelPerBlock);
15321563
if (linePosition == rect.x) {
15331564
rect.x++; // block tags are drawn only inside the block
15341565
}
@@ -1577,6 +1608,9 @@ public Rectangle getTagSelectionRectangle(SignalSelection tag, boolean marker, i
15771608
rect = useRect;
15781609
}
15791610

1611+
TagTiming timing = computeTagTiming(tag);
1612+
double position = timing.position;
1613+
double length = timing.length;
15801614
if (marker) {
15811615

15821616
int rWidth = pixelPerChannel / (3 * tagCnt); // 1/3 of the height for this tag
@@ -1585,12 +1619,12 @@ public Rectangle getTagSelectionRectangle(SignalSelection tag, boolean marker, i
15851619
} else if (rWidth < 5) {
15861620
rWidth = 5;
15871621
}
1588-
rect.x = (int) (tag.getPosition() * pixelPerSecond) - rWidth / 2;
1622+
rect.x = (int) (position * pixelPerSecond) - rWidth / 2;
15891623
rect.width = rWidth;
15901624

15911625
} else {
1592-
rect.x = (int) (tag.getPosition() * pixelPerSecond);
1593-
rect.width = (int) (tag.getLength() * pixelPerSecond);
1626+
rect.x = (int) (position * pixelPerSecond);
1627+
rect.width = (int) (length * pixelPerSecond);
15941628
}
15951629

15961630
return rect;
@@ -1797,7 +1831,7 @@ public SignalSelection getChannelSelection(float fromPosition, float toPosition,
17971831
*/
17981832
protected SignalSelection transformToMarkerSelection(SignalSelection selection) {
17991833

1800-
double startPosition = selection.getPosition();
1834+
double startPosition = computeTagTiming(selection).position;
18011835
int sampleAtPoint = (int) (startPosition * samplingFrequency);
18021836
float newStartPosition = sampleAtPoint / samplingFrequency;
18031837

@@ -2039,23 +2073,26 @@ public ArrayList<PositionedTag> getTagsAtPoint(Point point, ArrayList<Positioned
20392073
continue;
20402074
}
20412075

2076+
TagTiming timing = computeTagTiming(tag);
2077+
double position = timing.position;
2078+
double length = timing.length;
20422079
if (tag.getStyle().getType() == SignalSelectionType.BLOCK) {
2043-
if (time >= tag.getPosition() && time < (tag.getPosition() + tag.getLength())) {
2080+
if (time >= position && time < position + length) {
20442081
tagBounds = getPixelBlockTagBounds(tag, tag.isMarker(), tagCnt, cnt, viewportPoint, viewportSize, plotSize, comparing, tempBounds);
20452082
if (tagBounds.contains(point)) {
20462083
list.add(new PositionedTag(tag, tagIndex));
20472084
}
20482085
}
20492086
} else if (tag.getStyle().getType() == SignalSelectionType.CHANNEL) {
20502087
if (tag.getChannel() == channel) {
2051-
if (tag.isMarker() || (time >= tag.getPosition() && time < tag.getEndPosition())) {
2088+
if (tag.isMarker() || (time >= position && time < position + length)) {
20522089
tagBounds = getPixelChannelTagBoundsInChannel(tag, tag.isMarker(), tagCnt, cnt, viewChannel, comparing, tempBounds);
20532090
if (tagBounds.contains(point)) {
20542091
list.add(new PositionedTag(tag, tagIndex));
20552092
}
20562093
}
20572094
} else if (tag.getChannel() == Tag.CHANNEL_NULL) {
2058-
if (tag.isMarker() || (time >= tag.getPosition() && time < (tag.getPosition() + tag.getLength()))) {
2095+
if (tag.isMarker() || (time >= position && time < position + length)) {
20592096
tagBounds = getPixelBlockTagBounds(tag, tag.isMarker(), tagCnt, cnt, viewportPoint, viewportSize, plotSize, comparing, tempBounds);
20602097
if (tagBounds.contains(point)) {
20612098
list.add(new PositionedTag(tag, tagIndex));

svarog/src/main/java/org/signalml/app/view/signal/SignalView.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1242,8 +1242,9 @@ public void showTag(Tag tag) {
12421242
JViewport viewport = scrollPane.getViewport();
12431243

12441244
Dimension viewportSize = viewport.getExtentSize();
1245-
int startX = plot.timeToPixel(tag.getPosition());
1246-
int endX = plot.timeToPixel(tag.getPosition() + tag.getLength());
1245+
TagTiming tagTiming = plot.computeTagTiming(tag);
1246+
int startX = plot.timeToPixel(tagTiming.position);
1247+
int endX = plot.timeToPixel(tagTiming.position + tagTiming.length);
12471248

12481249
int optimalX = startX - (viewportSize.width - (endX - startX)) / 2;
12491250

0 commit comments

Comments
 (0)