Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/open-ephys/GUI
Browse files Browse the repository at this point in the history
  • Loading branch information
Josh Siegle committed Mar 2, 2016
2 parents e3df200 + ef8174f commit 603bdbb
Show file tree
Hide file tree
Showing 28 changed files with 501 additions and 51 deletions.
Binary file modified Builds/Linux/build/rhd2000.bit
Binary file not shown.
Binary file removed Builds/MacOSX/build/Debug/libokFrontPanel.dylib
Binary file not shown.
Binary file removed Builds/MacOSX/build/Debug/rhd2000.bit
Binary file not shown.
Binary file modified Resources/Bitfiles/rhd2000.bit
Binary file not shown.
Binary file modified Resources/Bitfiles/rhd2000_usb3.bit
Binary file not shown.
69 changes: 69 additions & 0 deletions Resources/Python/record_control_example_client.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
"""
A zmq client to test remote control of open-ephys GUI
"""

import zmq
import os
import time


def run_client():

# Basic start/stop commands
start_cmd = 'StartRecord'
stop_cmd = 'StopRecord'

# Example settings
rec_dir = os.path.join(os.getcwd(), 'Output_RecordControl')
print "Saving data to:", rec_dir

# Some commands
commands = [start_cmd + ' RecDir=%s' % rec_dir,
start_cmd + ' PrependText=Session01 AppendText=Condition01',
start_cmd + ' PrependText=Session01 AppendText=Condition02',
start_cmd + ' PrependText=Session02 AppendText=Condition01',
start_cmd,
start_cmd + ' CreateNewDir=1']

# Connect network handler
ip = '127.0.0.1'
port = 5556
timeout = 1.

url = "tcp://%s:%d" % (ip, port)

with zmq.Context() as context:
with context.socket(zmq.REQ) as socket:
socket.RCVTIMEO = int(timeout * 1000) # timeout in milliseconds
socket.connect(url)

# Finally, start data acquisition
socket.send('StartAcquisition')
answer = socket.recv()
print answer
time.sleep(5)

for start_cmd in commands:

for cmd in [start_cmd, stop_cmd]:
socket.send(cmd)
answer = socket.recv()
print answer

if 'StartRecord' in cmd:
# Record data for 5 seconds
time.sleep(5)
else:
# Stop for 1 second
time.sleep(1)

# Finally, stop data acquisition; it might be a good idea to
# wait a little bit until all data have been written to hard drive
time.sleep(0.5)
socket.send('StopAcquisition')
answer = socket.recv()
print answer


if __name__ == '__main__':
run_client()
32 changes: 31 additions & 1 deletion Source/CoreServices.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,16 @@ void setRecordingStatus(bool enable)
getControlPanel()->setRecordState(enable);
}

bool getAcquisitionStatus()
{
return getControlPanel()->getAcquisitionState();
}

void setAcquisitionStatus(bool enable)
{
getControlPanel()->setAcquisitionState(enable);
}

void sendStatusMessage(const String& text)
{
getBroadcaster()->sendActionMessage(text);
Expand All @@ -77,6 +87,26 @@ int64 getSoftwareTimestamp()
return getMessageCenter()->getTimestamp(true);
}

void setRecordingDirectory(String dir)
{
getControlPanel()->setRecordingDirectory(dir);
}

void createNewRecordingDir()
{
getControlPanel()->labelTextChanged(NULL);
}

void setPrependTextToRecordingDir(String text)
{
getControlPanel()->setPrependText(text);
}

void setAppendTextToRecordingDir(String text)
{
getControlPanel()->setAppendText(text);
}

namespace RecordNode
{
void createNewrecordingDir()
Expand Down Expand Up @@ -105,4 +135,4 @@ int addSpikeElectrode(SpikeRecordInfo* elec)
}
};

};
};
18 changes: 18 additions & 0 deletions Source/CoreServices.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@ bool getRecordingStatus();
/** Activated or deactivates recording */
void setRecordingStatus(bool enable);

/** Returns true if the GUI is acquiring data */
bool getAcquisitionStatus();

/** Activates or deactivates data acquisition */
void setAcquisitionStatus(bool enable);

/** Sends a string to the message bar */
void sendStatusMessage(const String& text);

Expand All @@ -59,6 +65,18 @@ int64 getGlobalTimestamp();
/** Gets the software timestamp based on a high resolution timer aligned to the start of each processing block */
int64 getSoftwareTimestamp();

/** Set new recording directory */
void setRecordingDirectory(String dir);

/** Create new recording directory */
void createNewRecordingDir();

/** Manually set the text to be prepended to the recording directory */
void setPrependTextToRecordingDir(String text);

/** Manually set the text to be appended to the recording directory */
void setAppendTextToRecordingDir(String text);

namespace RecordNode
{
/** Forces creation of new directory on recording */
Expand Down
2 changes: 1 addition & 1 deletion Source/Processors/ArduinoOutput/ArduinoOutput.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
#include <stdio.h>

ArduinoOutput::ArduinoOutput()
: GenericProcessor("Arduino Output"), outputChannel(13), inputChannel(-1), state(true), deviceSelected(false)
: GenericProcessor("Arduino Output"), outputChannel(13), inputChannel(-1), state(true), deviceSelected(false), acquisitionIsActive(false)
{

}
Expand Down
93 changes: 74 additions & 19 deletions Source/Processors/DataThreads/RHD2000Editor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -631,12 +631,15 @@ RHD2000Editor::RHD2000Editor(GenericProcessor* parentNode,
// add HW audio parameter selection
audioInterface = new AudioInterface(board, this);
addAndMakeVisible(audioInterface);
audioInterface->setBounds(175, 65, 65, 50);
audioInterface->setBounds(179, 58, 70, 50);

clockInterface = new ClockDivideInterface(board, this);
addAndMakeVisible(clockInterface);
clockInterface->setBounds(179, 82, 70, 50);

adcButton = new UtilityButton("ADC 1-8", Font("Small Text", 13, Font::plain));
adcButton->setRadius(3.0f);
adcButton->setBounds(175,100,65,18);
adcButton->setBounds(179,108,70,18);
adcButton->addListener(this);
adcButton->setClickingTogglesState(true);
adcButton->setTooltip("Enable/disable ADC channels");
Expand Down Expand Up @@ -742,7 +745,7 @@ void RHD2000Editor::handleAsyncUpdate()

String path(CoreServices::RecordNode::getRecordingPath().getFullPathName()
+ File::separatorString + "impedance_measurement.xml");
std::cout << "Saving impedance measurements in " << path << std::endl;
std::cout << "Saving impedance measurements in " << path << "\n";
File file(path);

if (!file.getParentDirectory().exists())
Expand Down Expand Up @@ -840,17 +843,17 @@ void RHD2000Editor::buttonEvent(Button* button)
{
board->enableAdcs(button->getToggleState());
// board->updateChannelNames();
std::cout << "ADC Button toggled" << std::endl;
std::cout << "ADC Button toggled" << "\n";
CoreServices::updateSignalChain(this);
std::cout << "Editor visible." << std::endl;
std::cout << "Editor visible." << "\n";
}
else if (button == dacTTLButton)
{
board->setTTLoutputMode(dacTTLButton->getToggleState());
}
else if (button == dspoffsetButton && !acquisitionIsActive)
{
std::cout << "DSP offset " << button->getToggleState() << std::endl;
std::cout << "DSP offset " << button->getToggleState() << "\n";
board->setDSPOffset(button->getToggleState());
}
else if (button == ledButton)
Expand Down Expand Up @@ -930,6 +933,7 @@ void RHD2000Editor::saveCustomParameters(XmlElement* xml)
xml->setAttribute("save_impedance_measurements",saveImpedances);
xml->setAttribute("auto_measure_impedances",measureWhenRecording);
xml->setAttribute("LEDs", ledButton->getToggleState());
xml->setAttribute("ClockDivideRatio", clockInterface->getClockDivideRatio());
}

void RHD2000Editor::loadCustomParameters(XmlElement* xml)
Expand All @@ -952,6 +956,7 @@ void RHD2000Editor::loadCustomParameters(XmlElement* xml)
saveImpedances = xml->getBoolAttribute("save_impedance_measurements");
measureWhenRecording = xml->getBoolAttribute("auto_measure_impedances");
ledButton->setToggleState(xml->getBoolAttribute("LEDs", true),sendNotification);
clockInterface->setClockDivideRatio(xml->getIntAttribute("ClockDivideRatio"));
}


Expand Down Expand Up @@ -1027,8 +1032,8 @@ void BandwidthInterface::labelTextChanged(Label* label)

actualUpperBandwidth = board->setUpperBandwidth(requestedValue);

std::cout << "Setting Upper Bandwidth to " << requestedValue << std::endl;
std::cout << "Actual Upper Bandwidth: " << actualUpperBandwidth << std::endl;
std::cout << "Setting Upper Bandwidth to " << requestedValue << "\n";
std::cout << "Actual Upper Bandwidth: " << actualUpperBandwidth << "\n";
label->setText(String(round(actualUpperBandwidth*10.f)/10.f), dontSendNotification);

}
Expand All @@ -1049,8 +1054,8 @@ void BandwidthInterface::labelTextChanged(Label* label)

actualLowerBandwidth = board->setLowerBandwidth(requestedValue);

std::cout << "Setting Lower Bandwidth to " << requestedValue << std::endl;
std::cout << "Actual Lower Bandwidth: " << actualLowerBandwidth << std::endl;
std::cout << "Setting Lower Bandwidth to " << requestedValue << "\n";
std::cout << "Actual Lower Bandwidth: " << actualLowerBandwidth << "\n";

label->setText(String(round(actualLowerBandwidth*10.f)/10.f), dontSendNotification);
}
Expand Down Expand Up @@ -1157,7 +1162,7 @@ void SampleRateInterface::comboBoxChanged(ComboBox* cb)
{
board->setSampleRate(cb->getSelectedId()-1);

std::cout << "Setting sample rate to index " << cb->getSelectedId()-1 << std::endl;
std::cout << "Setting sample rate to index " << cb->getSelectedId()-1 << "\n";

CoreServices::updateSignalChain(editor);
}
Expand Down Expand Up @@ -1286,15 +1291,15 @@ void HeadstageOptionsInterface::buttonClicked(Button* button)
if (!(editor->acquisitionIsActive) && board->foundInputSource())
{

//std::cout << "Acquisition is not active" << std::endl;
//std::cout << "Acquisition is not active" << "\n";
if ((button == hsButton1) && (board->getChannelsInHeadstage(hsNumber1) == 32))
{
if (channelsOnHs1 == 32)
channelsOnHs1 = 16;
else
channelsOnHs1 = 32;

//std::cout << "HS1 has " << channelsOnHs1 << " channels." << std::endl;
//std::cout << "HS1 has " << channelsOnHs1 << " channels." << "\n";

hsButton1->setLabel(String(channelsOnHs1));
board->setNumChannels(hsNumber1, channelsOnHs1);
Expand Down Expand Up @@ -1390,7 +1395,7 @@ void AudioInterface::labelTextChanged(Label* label)

actualNoiseSlicerLevel = board->setNoiseSlicerLevel(requestedValue);

std::cout << "Setting Noise Slicer Level to " << requestedValue << std::endl;
std::cout << "Setting Noise Slicer Level to " << requestedValue << "\n";
label->setText(String((roundFloatToInt)(actualNoiseSlicerLevel)), dontSendNotification);

}
Expand Down Expand Up @@ -1424,16 +1429,66 @@ void AudioInterface::paint(Graphics& g)
{

g.setColour(Colours::darkgrey);

g.setFont(Font("Small Text",9,Font::plain));

g.drawText(name, 0, 0, 200, 15, Justification::left, false);

g.drawText("Level: ", 0, 10, 200, 20, Justification::left, false);
}


// Clock Divider options
ClockDivideInterface::ClockDivideInterface(RHD2000Thread* board_,
RHD2000Editor* editor_) :
board(board_)
, editor(editor_)

{
divideRatioSelection = new Label("Clock Divide", lastDivideRatioString);
divideRatioSelection->setEditable(true,false,false);
divideRatioSelection->addListener(this);
divideRatioSelection->setBounds(30,10,30,20);
divideRatioSelection->setColour(Label::textColourId, Colours::darkgrey);
addAndMakeVisible(divideRatioSelection);
}

void ClockDivideInterface::labelTextChanged(Label* label)
{
if (board->foundInputSource())
{
if (label == divideRatioSelection)
{
Value val = label->getTextValue();
int requestedValue = int(val.getValue());

if (requestedValue < 1 || requestedValue > 65534)
{
CoreServices::sendStatusMessage("Value must be between 1 and 65534.");
label->setText(lastDivideRatioString, dontSendNotification);
return;
}

actualDivideRatio = board->setClockDivider(requestedValue);
lastDivideRatioString = String(actualDivideRatio);

std::cout << "Setting clock divide ratio to " << actualDivideRatio << "\n";
label->setText(lastDivideRatioString, dontSendNotification);
}
}
}

void ClockDivideInterface::setClockDivideRatio(int value)
{
actualDivideRatio = board->setClockDivider(value);
divideRatioSelection->setText(String(actualDivideRatio), dontSendNotification);
}

void ClockDivideInterface::paint(Graphics& g)
{

g.setColour(Colours::darkgrey);
g.setFont(Font("Small Text",9,Font::plain));
g.drawText(name, 0, 0, 200, 15, Justification::left, false);
g.drawText("Ratio: ", 0, 10, 200, 20, Justification::left, false);
}

// DSP Options --------------------------------------------------------------------

Expand Down Expand Up @@ -1472,8 +1527,8 @@ void DSPInterface::labelTextChanged(Label* label)

actualDspCutoffFreq = board->setDspCutoffFreq(requestedValue);

std::cout << "Setting DSP Cutoff Freq to " << requestedValue << std::endl;
std::cout << "Actual DSP Cutoff Freq: " << actualDspCutoffFreq << std::endl;
std::cout << "Setting DSP Cutoff Freq to " << requestedValue << "\n";
std::cout << "Actual DSP Cutoff Freq: " << actualDspCutoffFreq << "\n";
label->setText(String(round(actualDspCutoffFreq*10.f)/10.f), dontSendNotification);

}
Expand Down
Loading

0 comments on commit 603bdbb

Please sign in to comment.