symphony-das / symphony-matlab Goto Github PK
View Code? Open in Web Editor NEWSymphony Data Acquisition System
Home Page: http://symphony-das.github.io
License: MIT License
Symphony Data Acquisition System
Home Page: http://symphony-das.github.io
License: MIT License
The preset window can become clogged with many presets for each of many protocols. A method to filter these would be useful. At a minimum, having an option to show only those for the currently active protocol would be good.
When you change the label of a source, nested epoch groups linked to that source do not get there source label updated in the entity tree.
updateNodeNamesForSourceSet
needs to use source.getAllEpochGroups
instead of source.getEpochGroups
.
Hi,
Can I acquire data from serial port?
I have a PCB board that uses the Intan RHD 2132 chip. The board has 32 channels and a sampling rate of 1000 samples per a second, so it returns 32 data points every millisecond. The board interfaces with the computer with USB SPI. Can I acquire the data from my custom PCB in with Symphony?
It would be nice to have something like the "startup file", a script that runs when Symphony starts, for cleanup. A "cleanup file" sounds right.
Per Khris:
I've found myself desiring a specific enhancement where Symphony would support class folders.
If anyone else wants it, here is the change I've made on our local machines. It doesn't require recompiling Symphony-core so I've just modified our Symphony installer (.mlappinstall) rather than repackaging it. Obviously, this will revert if an update comes out.The original line (74) is:
elseif ~isempty(name) && name(1) == '+'And I've changed it to:
elseif ~isempty(name) && (name(1) == '+' || name(1) == '@')
There is a lot more information that could be shown in the data manager in order to make browsing the data tree more efficient and simple. Currently, the epoch's time is displayed, for instance, but, for protocols with changing variables over epochs, that value could be displayed. For a direction selectivity measurement, for example, it should display the movement direction angle for each epoch: "angle: 60". This is already pulled out and displayed within the epoch's data area on the right, but it's not currently available for browsing the tree quickly.
Symphony shows a really unhelpful traceback when an exception occurs in Controller.onCompletedEpoch (usually when an exception occurs in a FigureHandler or Protocol.completeEpoch).
Per Sam Cooler:
I'm doing work that involves a lot of debugging. But my errors keep coming up with file/line reference to the Controller.m, with traceback info lost:
Warning: DEBUG: Struct contents reference
from a non-struct array object.
Error using
symphonyui.core.Controller/process (line 284)
Struct contents reference from a non-struct
array object.Error in symphonyui.core.Controller/run (line
249)
obj.process();
Some users would like to be able to update existing protocol presets after they've been created (rather than delete and recreate them). I'm not sure how this would work from a UI perspective without over-complicating things.
When you apply presets and a field of that protocol is being edited, it will not apply the preset to that field.
We currently use "ANALOG_IN.0" and "DIGITAL_IN.0" style stream names for HekaDaqController, and "ai0" and "diport0" style stream names for NiDaqController. It would be nice to settle on a common standard here.
The NI style is used in National Instruments documentation/software. The HEKA style was developed specifically for Symphony. HEKA does not have a standard stream name approach AFAIK. Therefore it probably makes sense just to use the NI style across both DaqControllers.
Only the 32bit version of NationalInstruments.DAQmx.dll is bundled with Symphony. That should be the 64bit version!
We'd like our actions during the course of the experiment to be less tied to the durations of procol epoch sets, always waiting on the rig to pick the next protocol's parameters. Typically, I know the first several things I'm going to do to a cell, once I'm attached well. Some cells have 30 minutes of pre-determined protocol sets, and I don't need to watch all the results as they come in.
So I propose a new feature, which is an experiment session queue, in which protocols, with params encapsulated as presets, chosen from the list, are added and ordered and executed one after the other, in a visual queue GUI. The queue can be reordered and modified (drag and drop?).
The play/pause/stop controls are then moved to this queue window. The protocol browser, as it is now, is used to create and modify the presets. That is, its behavior is not connected to the run state. The buttons at the bottom of this are then "add as preset" "add to queue" "add to queue and as preset". The preset browser has buttons "add as next" "add as last", and context menus to "add as preset".
-sam
The HEKA stuff requires Visual C++ 2010 runtime. Instead of requiring thats users install it on there own, see if we can include it in the release package (if it's not too large).
Probably located in: C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\redist\x64\Microsoft.VC100.CRT
Things feel a bit slow in the UI, especially on first load. This is partly unavoidable because MATLAB is slow but there might be some areas where things could be improved. In areas where they can't, showing spinners is helpful to communicate that things are working after the user clicks something (the Initialize Rig window really needs a spinner because it can take some time after the user clicks "Initialize" before anything happens).
Descriptor value getters like:
Device.getConfigurationSetting()
Device.hasConfigurationSetting()
Entity.getProperty()
Can be more efficient by not retrieving all the descriptors and using findByName() and instead getting the value from the core map directly.
For example:
Current:
function v = getConfigurationSetting(obj, name)
% Gets the value of an existing configuration setting
descriptors = obj.getConfigurationSettingDescriptors();
d = descriptors.findByName(name);
if isempty(d)
error([name ' does not exist']);
end
v = d.value;
end
More efficient:
function v = getConfigurationSetting(obj, name)
% Gets the value of an existing configuration setting
v = obj.tryCoreWithReturn(@()obj.cobj.Configuration.Item(name));
v = obj.valueFromPropertyValue(convert(v));
end
Jacob reports that if he runs a preset and records a large number of epochs, he is able to run the next preset while the main window shows that Symphony is "stopped". We tried to reproduce this briefly but were unable to make it happen. I suspect it occurs when you record a large number of epochs and the data manager takes a while to populate the epoch list. During this time, it may be able to run the next preset but have the state change event swallowed by the data manager or something else in the system.
Current HekaDaqController.m
can create only one kind of daq.
cobj = Heka.HekaDAQController(double(Heka.NativeInterop.ITCMM.USB18_ID), 0);
But I need to create cobj
based on board (ITC1600_ID or USB18_ID). Is it advisable to modify HekaDaqController
constructor to take an argument and create cobj
based on it ?
classdef HekaDaqController < symphonyui.core.DaqController
enumeration
ITC1600, ITC18
...
function obj = HekaDaqController(board)
....
if(board == HekaDaqController.ITC18)
cobj = Heka.HekaDAQController(double(Heka.NativeInterop.ITCMM.USB18_ID), 0);
elseif(board == HekaDaqController.ITC1600)
cobj = Heka.HekaDAQController(double(Heka.NativeInterop.ITCMM.ITC1600_ID), 0);
else
error(['board should either be ITC1600 or ITC18']);
end
Kindly clarify
MathWorks changed some stuff about the Documentation viewer in R2016b and now the Symphony documentation has some visual bugs:
Some users forget to create a new epoch group or accidentally close an epoch group too soon, causing their data not to be organized in the way they want. The ability to split and merge epoch groups would go a long way toward alleviating this issue.
To reproduce, put a disp('start!') in controllerDidStartHardware and run something like SingleSpot with pre, stim, and tail time of 10ms and 5 num averages. You'll see "start!" is printed more than 5 times.
To reproduce:
Importing Symphony stuff from packages is quite a bit of typing. It would be nice if there was a convenience package with a short name like sym so the a user could write something like sym.Protocol instead of symphonyui.core.Protocol and sym.ResponseFigure instead of symphonyui.builtin.figures.ResponseFigure.
Some users may want to view Response data while it's being recorded. Currently, the getData method caches the data on first use and always returns the cached data. The user should be able to get around this by adding a clearDataCache method to Response which they can call before calling getData.
As users write more protocols, the dropdown list for selecting the current protocol can become frustrating to navigate. It would be nice if users could hide protocols they're not interested in seeing. A new page under Configure > Options would probably be the best place for this.
An epoch's duration is currently calculated as the duration of its longest stimulus. If you remove all stimuli before persisting an epoch its duration will be persisted as zero even if it has responses. The duration should really be calculated as its longest stimulus OR response.
Mike reports that as Symphony data files grow beyond 1GB, the app seems to slow down and it becomes less than pleasant to use.
The Symphony UI does not look great on Windows 10, especially with a hi-res display. It would be great to support this better.
When a protocol is run, and stopped during an epoch, sometimes the epoch stage display runs through completion. However, the data is dumped and not recorded as an epoch. This means that it is sometimes necessary to wait for an entire extra epoch to run to ensure that the last desired epoch is saved, which is time consuming if epochs are long. Could the stop button be altered to have a "stop after this epoch is completed" functionality?
There are cases where a FigureHandler may want to handle interval epochs. Right now, only "true" epochs are passed to the handleEpoch
method of handlers. It might make sense to pass all epochs to handlers and let the handler decide if it wants to deal with "interval" epochs.
Adding an isInterval
method to Epoch
would also be helpful for this.
When you change a protocol property, the figure handlers close (by design). This causes the stored sweep in the builtin handlers to disappear. It would be nice if the stored sweeps stuck around until they were explicitly cleared.
Here is the pattern to store info across figure handlers:
classdef Figure < symphonyui.core.FigureHandler
methods
function obj = Figure()
% Get stored info.
averages = obj.storedAverages();
end
function store(obj)
% Store some data.
obj.storedAverages([1 2 3]);
end
end
methods (Static)
function averages = storedAverages(averages)
% This method stores means across figure handlers.
persistent stored;
if nargin > 0
stored = averages;
end
averages = stored;
end
end
end
At the Schwartz lab, we sometimes make mistakes. One of those mistakes looks like pressing the wrong button, viewing (rather than recording) a bunch of epochs, then realizing they were not recorded at all. In Symphony 1, a large red text indicator made it clear when epochs were not being recorded. In Symphony 2, this is much more subtle, with the only sign being "viewing" rather than "recording" at the bottom.
To ameliorate this issue, it would be good to have some warning, or perhaps a fail-safe mechanism. Something like the red text, displayed when a data file is open but not being written to, would be a good place to start. Or, perhaps, a confirmation step required for viewing-only when a file is open. Alternatively, all epochs (from both view and record mode) could be saved automatically, then those marked as "view mode" would be not stored with the saved recording h5, unless they were mode-switched beforehand.
Hi Mark,
Thanks for integrating Heka device support. I am trying to integrate rig toggle switches to control the state (start, stop and pause) of acquisition software.
Can you please review below approach and advise on it ?
classdef RigSwitches < symphonyui.builtin.devices.UnitConvertingDevice
events
RunProtocol
DontSave
UpdateFigures
StopProtocol
end
methods
function obj = RigSwitches(name)
[email protected](name, symphonyui.core.Measurement.UNITLESS);
end
function checkStatus(obj, response, index)
n = length(response);
state = response(n);
switch(index)
case 1
notify(obj, 'RunProtocol', symphonyui.app.AppEventData(state))
end
end
end
end
classdef HekaITC18Multiclamp < symphonyui.core.descriptions.RigDescription
....
methods
function obj = HekaITC18Multiclamp()
import symphonyui.builtin.daqs.*;
import symphonyui.builtin.devices.*;
import fi.helsinki.biosci.ala-alaurila.devices.*;
....
rigSwitch1 = RighSwitch('rigSwitch1').bindStream(daq.getStream('DIGITAL_IN.1'))
daq.getStream('DIGITAL_IN.1').setBitPosition(rigSwitch1, 1)
...
obj.devices = {amp1, amp2, green, blue, trigger1, trigger2, rigSwitch1};
classdef Pulse < symphonyui.core.Protocol
....
function prepareEpoch(obj, epoch)
.....
.....
d = obj.rig.getDevice('rigSwitch1');
r = epoch.response(d)
d.checkStatus(r, 1)
If am doing some thing wrong, kindly correct me
Thanks,
Sathish
Sources should be shown in the data manager by creation date. This isn't a problem when you initially make the sources because they naturally add in that order but the order becomes random when you reopen an existing file.
The loopback simulation doesn't provide anything close to a typical cell response which makes it hard to test online analysis before an experiment. Can we come up with another simulation that provides something closer to a typical cell response?
The symphonyui.core.CoreObject.dateTimeOffsetFromDatetime method is currently broken when your timezone is 'Europe/London'. The below code includes the fix.
function dto = dateTimeOffsetFromDatetime(obj, t) %#ok<INUSL>
if isempty(t.TimeZone)
error('Datetime ''TimeZone'' must be set');
end
t.Format = 'ZZZZZ';
tz = char(t);
if tz(1) == '+'
tz(1) = [];
elseif strcmp(tz, 'Z')
tz = '00:00';
end
offset = System.TimeSpan.Parse(tz);
dto = System.DateTimeOffset(t.Year, t.Month, t.Day, t.Hour, t.Minute, floor(t.Second), round(1000*rem(t.Second, 1)), offset);
end
Keep your pointer over a "View Only" or "Record" button during the run of a protocol. When the protocol completes, the button you're hovering over will stay disabled until you move your pointer off of it.
JIDE offers a pretty cool searchable JComboBox that would make finding a protocol in a long list of protocols easier. You just click on the ComboBox and start typing:
Here's some sample code:
import com.jidesoft.combobox.*;
import com.jidesoft.plaf.LookAndFeelFactory;
import com.jidesoft.swing.*;
JComboBox comboBox = new JComboBox(names);
comboBox.setEditable(false); // combobox searchable only works when combobox is not editable.
SearchableUtils.installSearchable(comboBox);
Per Sam Cooler:
I spent a while dealing with an issue today, getting digital output to work from the ITC-18. Turns out, the ITC front panel is doport1, not doport0, and that the bit position is what is equivalent to Symphony 1's DIGITAL_OUT.x label.
Though I've got it figured out now, I think a mapping from physical ports to port name strings (and bit position) would be helpful for others, for the future.
Ah, I meant a text information mapping. I'm just saying to add to the symphony documentation, or example rig configs, or somewhere, the words "The ITC-18 front panel digital lines are doport1, and are accessed individually using the bit positions"
We persist Response and Stimulus data with display units but the Stimulus object itself still has base units. We should change this so everything is display units. This involves changing the Units
property of Stimulus
to be display units instead of base units.
It looks like we missed adding series resistance to the .NET version of the multi clamp data structure.
We should add it and make sure it is recorded in the data file.
Some windows don't need to be resized. Set their figures to Resize=off.
Some classes that derive from CoreObject have properties that call cellArrayFromEnumerable. For example, EpochGroup
:
function b = get.epochBlocks(obj)
b = obj.cellArrayFromEnumerable(obj.cobj.EpochBlocks, @symphonyui.core.persistent.EpochBlock);
end
These properties should probably be changed to methods because they're potentially long running. The only exception might be when the enumerable list is guaranteed to be short.
For the example above, the method would look like:
function b = getEpochBlocks(obj)
b = obj.cellArrayFromEnumerable(obj.cobj.EpochBlocks, @symphonyui.core.persistent.EpochBlock);
end
To repeat:
The stop button has no effect. Symphony is now frozen.
HEKA releases new ITC drivers a while ago. It looks like they're more stable, more capable, and actually being maintained by HEKA. We should create a new DAQController for these drivers.
When a release of Symphony is made, the symphony-matlab repo is tagged but the symphony-core repo is not. Because of this, there's not a great way to go back and look at the state of the core source code at particular release versions.
If we add the core repo as a submodule to the matlab module, the matlab repo tag will allow us to preserve the revision of the core repo used to make that release. It will also make it easier to automate more of the release process, perhaps with a "release.m" or "deploy.m" script.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.