Skip to content

Commit

Permalink
Merge pull request #160 from SainsburyWellcomeCentre/aeon-acquisition
Browse files Browse the repository at this point in the history
Add operators for monitoring Harp device synchronization status
  • Loading branch information
glopesdev authored Oct 16, 2023
2 parents c71bf2e + 72c4de2 commit b1ce707
Show file tree
Hide file tree
Showing 3 changed files with 221 additions and 1 deletion.
2 changes: 1 addition & 1 deletion src/Aeon.Acquisition/Aeon.Acquisition.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<PackageTags>Bonsai Rx Project Aeon Acquisition</PackageTags>
<TargetFramework>net472</TargetFramework>
<VersionPrefix>0.5.0</VersionPrefix>
<VersionSuffix>build231007</VersionSuffix>
<VersionSuffix>build231008</VersionSuffix>
</PropertyGroup>

<ItemGroup>
Expand Down
75 changes: 75 additions & 0 deletions src/Aeon.Acquisition/HeartbeatMonitor.bonsai
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<?xml version="1.0" encoding="utf-8"?>
<WorkflowBuilder Version="2.8.1"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:rx="clr-namespace:Bonsai.Reactive;assembly=Bonsai.Core"
xmlns:harp="clr-namespace:Bonsai.Harp;assembly=Bonsai.Harp"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns="https://bonsai-rx.org/2018/workflow">
<Description>Captures the sequence of heartbeats from the specified source as a named group.</Description>
<Workflow>
<Nodes>
<Expression xsi:type="ExternalizedMapping">
<Property Name="Name" />
</Expression>
<Expression xsi:type="rx:CreateObservable">
<Name />
<Workflow>
<Nodes>
<Expression xsi:type="ExternalizedMapping">
<Property Name="Name" />
</Expression>
<Expression xsi:type="SubscribeSubject">
<Name>DeviceEvents</Name>
</Expression>
<Expression xsi:type="harp:Parse">
<harp:Register xsi:type="harp:TimestampedTimestampSeconds" />
</Expression>
<Expression xsi:type="harp:ConvertTimestamped">
<Workflow>
<Nodes>
<Expression xsi:type="WorkflowInput">
<Name>Source1</Name>
</Expression>
<Expression xsi:type="ExternalizedMapping">
<Property Name="Value" DisplayName="Name" Category="Subject" />
</Expression>
<Expression xsi:type="PropertySource" TypeArguments="SubscribeSubject,sys:String">
<MemberName>Name</MemberName>
<Value>DeviceEvents</Value>
</Expression>
<Expression xsi:type="Combinator">
<Combinator xsi:type="rx:WithLatestFrom" />
</Expression>
<Expression xsi:type="MemberSelector">
<Selector>Item2</Selector>
</Expression>
<Expression xsi:type="WorkflowOutput" />
</Nodes>
<Edges>
<Edge From="0" To="3" Label="Source1" />
<Edge From="1" To="2" Label="Source1" />
<Edge From="2" To="3" Label="Source2" />
<Edge From="3" To="4" Label="Source1" />
<Edge From="4" To="5" Label="Source1" />
</Edges>
</Workflow>
</Expression>
<Expression xsi:type="WorkflowOutput" />
</Nodes>
<Edges>
<Edge From="0" To="1" Label="Source1" />
<Edge From="0" To="3" Label="Source2" />
<Edge From="1" To="2" Label="Source1" />
<Edge From="2" To="3" Label="Source1" />
<Edge From="3" To="4" Label="Source1" />
</Edges>
</Workflow>
</Expression>
<Expression xsi:type="WorkflowOutput" />
</Nodes>
<Edges>
<Edge From="0" To="1" Label="Source1" />
<Edge From="1" To="2" Label="Source1" />
</Edges>
</Workflow>
</WorkflowBuilder>
145 changes: 145 additions & 0 deletions src/Aeon.Acquisition/SynchronizerMonitor.bonsai
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
<?xml version="1.0" encoding="utf-8"?>
<WorkflowBuilder Version="2.8.1"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:rx="clr-namespace:Bonsai.Reactive;assembly=Bonsai.Core"
xmlns:harp="clr-namespace:Bonsai.Harp;assembly=Bonsai.Harp"
xmlns:num="clr-namespace:Bonsai.Numerics;assembly=Bonsai.Numerics"
xmlns:scr="clr-namespace:Bonsai.Scripting.Expressions;assembly=Bonsai.Scripting.Expressions"
xmlns="https://bonsai-rx.org/2018/workflow">
<Description>Provides continuous statistics and reports current time and device synchronization state.</Description>
<Workflow>
<Nodes>
<Expression xsi:type="WorkflowInput">
<Name>Source1</Name>
</Expression>
<Expression xsi:type="Combinator">
<Combinator xsi:type="rx:ToArray" />
</Expression>
<Expression xsi:type="rx:AsyncSubject">
<Name>HeartbeatSources</Name>
</Expression>
<Expression xsi:type="Combinator">
<Combinator xsi:type="rx:Merge" />
</Expression>
<Expression xsi:type="Combinator">
<Combinator xsi:type="rx:Merge" />
</Expression>
<Expression xsi:type="Combinator">
<Combinator xsi:type="rx:Delay">
<rx:DueTime>PT0.2S</rx:DueTime>
</Combinator>
</Expression>
<Expression xsi:type="SubscribeSubject">
<Name>SynchronizerEvents</Name>
</Expression>
<Expression xsi:type="harp:FilterRegister">
<harp:FilterType>Include</harp:FilterType>
<harp:Register xsi:type="harp:TimestampSeconds" />
</Expression>
<Expression xsi:type="Combinator">
<Combinator xsi:type="rx:BufferTrigger">
<rx:Count xsi:nil="true" />
<rx:TimeSpan>PT0.4S</rx:TimeSpan>
</Combinator>
</Expression>
<Expression xsi:type="rx:SelectMany">
<Name>UnwrapTimestamps</Name>
<Workflow>
<Nodes>
<Expression xsi:type="WorkflowInput">
<Name>Source1</Name>
</Expression>
<Expression xsi:type="Combinator">
<Combinator xsi:type="rx:Merge" />
</Expression>
<Expression xsi:type="MemberSelector">
<Selector>Seconds</Selector>
</Expression>
<Expression xsi:type="Combinator">
<Combinator xsi:type="rx:ToList" />
</Expression>
<Expression xsi:type="Format">
<Format>{0}@{1}</Format>
<Selector>Value,Seconds</Selector>
</Expression>
<Expression xsi:type="Combinator">
<Combinator xsi:type="rx:ToList" />
</Expression>
<Expression xsi:type="Combinator">
<Combinator xsi:type="rx:Zip" />
</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="4" Label="Source1" />
<Edge From="2" To="3" Label="Source1" />
<Edge From="3" To="6" Label="Source1" />
<Edge From="4" To="5" Label="Source1" />
<Edge From="5" To="6" Label="Source2" />
<Edge From="6" To="7" Label="Source1" />
</Edges>
</Workflow>
</Expression>
<Expression xsi:type="MemberSelector">
<Selector>Item1</Selector>
</Expression>
<Expression xsi:type="Combinator">
<Combinator xsi:type="num:DescriptiveStatistics" />
</Expression>
<Expression xsi:type="MemberSelector">
<Selector>Item2</Selector>
</Expression>
<Expression xsi:type="Combinator">
<Combinator xsi:type="rx:Zip" />
</Expression>
<Expression xsi:type="scr:ExpressionTransform">
<scr:Expression>new(
Item1 as Stats,
Item2 as Names)</scr:Expression>
</Expression>
<Expression xsi:type="SubscribeSubject">
<Name>HeartbeatSources</Name>
</Expression>
<Expression xsi:type="MemberSelector">
<Selector>Length</Selector>
</Expression>
<Expression xsi:type="Combinator">
<Combinator xsi:type="rx:WithLatestFrom" />
</Expression>
<Expression xsi:type="scr:ExpressionTransform">
<scr:Expression>new(
Item1.Stats.Mean as MeanTimestamp,
DateTime(1904, 1, 1) + TimeSpan.FromSeconds(Item1.Stats.Mean) as MeanUtcTimestamp,
Item2 as ExpectedDeviceCount,
Item1.Stats.Count as DeviceCount,
Item1.Stats.Maximum - Item1.Stats.Minimum as MaxDifference,
string.Join("\t", Item1.Names) as Elements)</scr:Expression>
</Expression>
<Expression xsi:type="WorkflowOutput" />
</Nodes>
<Edges>
<Edge From="0" To="1" Label="Source1" />
<Edge From="1" To="2" Label="Source1" />
<Edge From="2" To="3" Label="Source1" />
<Edge From="3" To="4" Label="Source1" />
<Edge From="4" To="5" Label="Source1" />
<Edge From="5" To="8" Label="Source1" />
<Edge From="6" To="7" Label="Source1" />
<Edge From="7" To="8" Label="Source2" />
<Edge From="8" To="9" Label="Source1" />
<Edge From="9" To="10" Label="Source1" />
<Edge From="9" To="12" Label="Source1" />
<Edge From="10" To="11" Label="Source1" />
<Edge From="11" To="13" Label="Source1" />
<Edge From="12" To="13" Label="Source2" />
<Edge From="13" To="14" Label="Source1" />
<Edge From="14" To="17" Label="Source1" />
<Edge From="15" To="16" Label="Source1" />
<Edge From="16" To="17" Label="Source2" />
<Edge From="17" To="18" Label="Source1" />
<Edge From="18" To="19" Label="Source1" />
</Edges>
</Workflow>
</WorkflowBuilder>

0 comments on commit b1ce707

Please sign in to comment.