Skip to content

Commit

Permalink
Merge pull request #511 from SainsburyWellcomeCentre/social-dev
Browse files Browse the repository at this point in the history
Add video stream selector to main control panel
  • Loading branch information
glopesdev authored Feb 9, 2024
2 parents 455d05e + 2983788 commit 674678e
Show file tree
Hide file tree
Showing 8 changed files with 420 additions and 83 deletions.
8 changes: 4 additions & 4 deletions bonsai/Bonsai.config
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<PackageConfiguration xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Packages>
<Package id="Aeon.Acquisition" version="0.5.0-build240101" />
<Package id="Aeon.Acquisition" version="0.5.0-build240102" />
<Package id="Aeon.Database" version="0.1.0-build231020" />
<Package id="Aeon.Environment" version="0.1.0-build240101" />
<Package id="Aeon.Environment" version="0.1.0-build240102" />
<Package id="Aeon.Foraging" version="0.1.0-build231202" />
<Package id="AsyncIO" version="0.1.69" />
<Package id="Bonsai" version="2.8.1" />
Expand Down Expand Up @@ -109,9 +109,9 @@
<AssemblyReference assemblyName="Harp.TimestampGeneratorGen3" />
</AssemblyReferences>
<AssemblyLocations>
<AssemblyLocation assemblyName="Aeon.Acquisition" processorArchitecture="MSIL" location="Packages\Aeon.Acquisition.0.5.0-build240101\lib\net472\Aeon.Acquisition.dll" />
<AssemblyLocation assemblyName="Aeon.Acquisition" processorArchitecture="MSIL" location="Packages\Aeon.Acquisition.0.5.0-build240102\lib\net472\Aeon.Acquisition.dll" />
<AssemblyLocation assemblyName="Aeon.Database" processorArchitecture="MSIL" location="Packages\Aeon.Database.0.1.0-build231020\lib\net472\Aeon.Database.dll" />
<AssemblyLocation assemblyName="Aeon.Environment" processorArchitecture="MSIL" location="Packages\Aeon.Environment.0.1.0-build240101\lib\net472\Aeon.Environment.dll" />
<AssemblyLocation assemblyName="Aeon.Environment" processorArchitecture="MSIL" location="Packages\Aeon.Environment.0.1.0-build240102\lib\net472\Aeon.Environment.dll" />
<AssemblyLocation assemblyName="Aeon.Foraging" processorArchitecture="MSIL" location="Packages\Aeon.Foraging.0.1.0-build231202\lib\net472\Aeon.Foraging.dll" />
<AssemblyLocation assemblyName="AsyncIO" processorArchitecture="MSIL" location="Packages\AsyncIO.0.1.69\lib\net40\AsyncIO.dll" />
<AssemblyLocation assemblyName="Basler.Pylon" processorArchitecture="X86" location="Packages\Bonsai.Pylon.0.3.0\build\net462\bin\x86\Basler.Pylon.dll" />
Expand Down
97 changes: 92 additions & 5 deletions workflows/social/Extensions/ControlPanel.bonsai
Original file line number Diff line number Diff line change
Expand Up @@ -1101,23 +1101,109 @@ FilteredWeight.Value - BaselinedWeight.Value as Baseline)</scr:Expression>
</Edges>
</Workflow>
</Expression>
<Expression xsi:type="ExternalizedMapping">
<Property Name="SelectedStream" />
</Expression>
<Expression xsi:type="GroupWorkflow">
<Name>OverheadCamera</Name>
<Name>CameraSelector</Name>
<Workflow>
<Nodes>
<Expression xsi:type="SubscribeSubject">
<Name>Trajectory</Name>
<Name>CameraTop</Name>
</Expression>
<Expression xsi:type="MemberSelector">
<Selector>Value.Image</Selector>
</Expression>
<Expression xsi:type="SubscribeSubject">
<Name>CameraWest</Name>
</Expression>
<Expression xsi:type="MemberSelector">
<Selector>Value.Image</Selector>
</Expression>
<Expression xsi:type="SubscribeSubject">
<Name>CameraEast</Name>
</Expression>
<Expression xsi:type="MemberSelector">
<Selector>Value.Image</Selector>
</Expression>
<Expression xsi:type="VisualizerMapping" />
<Expression xsi:type="SubscribeSubject">
<Name>FrameTrajectory</Name>
<Name>CameraNorth</Name>
</Expression>
<Expression xsi:type="MemberSelector">
<Selector>Value.Image</Selector>
</Expression>
<Expression xsi:type="SubscribeSubject">
<Name>CameraSouth</Name>
</Expression>
<Expression xsi:type="MemberSelector">
<Selector>Value.Image</Selector>
</Expression>
<Expression xsi:type="SubscribeSubject">
<Name>CameraNest</Name>
</Expression>
<Expression xsi:type="MemberSelector">
<Selector>Value.Image</Selector>
</Expression>
<Expression xsi:type="SubscribeSubject">
<Name>CameraPatch1</Name>
</Expression>
<Expression xsi:type="MemberSelector">
<Selector>Value.Image</Selector>
</Expression>
<Expression xsi:type="SubscribeSubject">
<Name>CameraPatch2</Name>
</Expression>
<Expression xsi:type="MemberSelector">
<Selector>Value.Image</Selector>
</Expression>
<Expression xsi:type="SubscribeSubject">
<Name>CameraPatch3</Name>
</Expression>
<Expression xsi:type="MemberSelector">
<Selector>Value.Image</Selector>
</Expression>
<Expression xsi:type="ExternalizedMapping">
<Property Name="SelectedStream" />
</Expression>
<Expression xsi:type="Combinator">
<Combinator xsi:type="p1:StreamSelector">
<p1:SelectedStream>CameraTop</p1:SelectedStream>
<p1:StreamNames>
<p1:string>CameraTop</p1:string>
<p1:string>CameraWest</p1:string>
<p1:string>CameraEast</p1:string>
<p1:string>CameraNorth</p1:string>
<p1:string>CameraSouth</p1:string>
<p1:string>CameraNest</p1:string>
<p1:string>CameraPatch1</p1:string>
<p1:string>CameraPatch2</p1:string>
<p1:string>CameraPatch3</p1:string>
</p1:StreamNames>
</Combinator>
</Expression>
<Expression xsi:type="WorkflowOutput" />
</Nodes>
<Edges>
<Edge From="0" To="1" Label="Source1" />
<Edge From="1" To="2" Label="Source1" />
<Edge From="1" To="19" Label="Source1" />
<Edge From="2" To="3" Label="Source1" />
<Edge From="3" To="19" Label="Source2" />
<Edge From="4" To="5" Label="Source1" />
<Edge From="5" To="19" Label="Source3" />
<Edge From="6" To="7" Label="Source1" />
<Edge From="7" To="19" Label="Source4" />
<Edge From="8" To="9" Label="Source1" />
<Edge From="9" To="19" Label="Source5" />
<Edge From="10" To="11" Label="Source1" />
<Edge From="11" To="19" Label="Source6" />
<Edge From="12" To="13" Label="Source1" />
<Edge From="13" To="19" Label="Source7" />
<Edge From="14" To="15" Label="Source1" />
<Edge From="15" To="19" Label="Source8" />
<Edge From="16" To="17" Label="Source1" />
<Edge From="17" To="19" Label="Source9" />
<Edge From="18" To="19" Label="Source10" />
<Edge From="19" To="20" Label="Source1" />
</Edges>
</Workflow>
</Expression>
Expand All @@ -1129,6 +1215,7 @@ FilteredWeight.Value - BaselinedWeight.Value as Baseline)</scr:Expression>
<Edge From="3" To="4" Label="Source1" />
<Edge From="5" To="6" Label="Source1" />
<Edge From="7" To="8" Label="Source1" />
<Edge From="13" To="14" Label="Source1" />
</Edges>
</Workflow>
</WorkflowBuilder>
61 changes: 61 additions & 0 deletions workflows/social/Extensions/StreamSelector.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
using Bonsai;
using System;
using System.ComponentModel;
using System.Linq;
using System.Reactive.Linq;
using System.Collections.ObjectModel;
using Bonsai.Expressions;

[Combinator]
[Description("Selects a specific stream by name from a set of input streams.")]
[WorkflowElementCategory(ElementCategory.Combinator)]
[DefaultProperty("StreamNames")]
public class StreamSelector
{
readonly Collection<string> streamNames = new Collection<string>();

[TypeConverter(typeof(SelectedStreamConverter))]
public string SelectedStream { get; set; }

public Collection<string> StreamNames
{
get { return streamNames; }
}

public IObservable<TSource> Process<TSource>(params IObservable<TSource>[] source)
{
var filteredStreams = new IObservable<TSource>[source.Length];
for (int i = 0; i < source.Length; i++)
{
var name = i < streamNames.Count ? streamNames[i] : string.Empty;
filteredStreams[i] = source[i].Where(_ => name == SelectedStream);
}

return Observable.Merge(filteredStreams);
}

class SelectedStreamConverter : StringConverter
{
public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
{
return true;
}

public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
{
StreamSelector selector = null;
var workflowBuilder = (WorkflowBuilder)context.GetService(typeof(WorkflowBuilder));
var descendants = workflowBuilder.Workflow.Descendants();
foreach (var node in descendants)
{
selector = ExpressionBuilder.GetWorkflowElement(node) as StreamSelector;
if (selector != null)
{
break;
}
}

return new StandardValuesCollection(selector.StreamNames);
}
}
}
12 changes: 9 additions & 3 deletions workflows/social/Social-AEON3.bonsai
Original file line number Diff line number Diff line change
Expand Up @@ -961,7 +961,12 @@
<Expression xsi:type="IncludeWorkflow" Path="Extensions\Logging.bonsai">
<WorkflowName>Social-AEON3.bonsai</WorkflowName>
</Expression>
<Expression xsi:type="IncludeWorkflow" Path="Extensions\ControlPanel.bonsai" />
<Expression xsi:type="ExternalizedMapping">
<Property Name="SelectedStream" />
</Expression>
<Expression xsi:type="IncludeWorkflow" Path="Extensions\ControlPanel.bonsai">
<SelectedStream>CameraTop</SelectedStream>
</Expression>
<Expression xsi:type="ExternalizedMapping">
<Property Name="EnvironmentConfigPath" />
</Expression>
Expand All @@ -979,8 +984,9 @@
</Expression>
</Nodes>
<Edges>
<Edge From="6" To="7" Label="Source1" />
<Edge From="8" To="9" Label="Source1" />
<Edge From="5" To="6" Label="Source1" />
<Edge From="7" To="8" Label="Source1" />
<Edge From="9" To="10" Label="Source1" />
</Edges>
</Workflow>
</WorkflowBuilder>
Loading

0 comments on commit 674678e

Please sign in to comment.