Skip to content

Commit

Permalink
Merge pull request #110 from AllenNeuralDynamics/feature-add-device-m…
Browse files Browse the repository at this point in the history
…etadata

Add operator to log device metadata
  • Loading branch information
bruno-f-cruz authored Nov 11, 2024
2 parents bc577ef + 69b9c5a commit 7aac10b
Show file tree
Hide file tree
Showing 21 changed files with 366 additions and 94 deletions.
10 changes: 10 additions & 0 deletions docs/articles/core-logging.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,20 @@ The first thing that should be defined is the root where all data will be saved
## Harp data
Once this `Subject` is created, other nodes can access to it. For instance, if one would like to save the data from a `Harp Device`:

### Without metadata
:::workflow
![SaveHarpData](~/workflows/SaveHarpData.bonsai)
:::

### With Metadata

Each device can be saved with metadata by providing the `device.yml` file information to the operator. This string can be passed manually or by using the `GetMetadata` node from the device-specific package.
For example, to log data from a `LicketySplit` device:

:::workflow
![SaveHarpDataWithMetadata](~/workflows/SaveHarpDataWithMetadata.bonsai)
:::

## Spinnaker camera
Similarly, for a `Spinnaker Camera`:

Expand Down
9 changes: 2 additions & 7 deletions docs/build.ps1
Original file line number Diff line number Diff line change
@@ -1,15 +1,10 @@
# Build device tables
$files = Get-ChildItem .\harp_devices_src\harp.device.*\software\bonsai\device.yml
$files_root = Get-ChildItem .\harp_devices_src\harp.device.*\device.yml
$files += $files_root
$files = Get-ChildItem .\harp_devices_src\harp.device.*\device.yml

foreach ($file in $files)
{
Write-Output "Generating schema tables for $file..."
$readmePath = (Get-Item $file).Directory.Parent.Parent.FullName + "\README.md"
if (-Not (Test-Path $readmePath)) {
$readmePath = (Get-Item $file).Directory.FullName + "\README.md"
}
$readmePath = (Get-Item $file).Directory.FullName + "\README.md"
$readmePath = ("." + (Resolve-Path -Relative $readmePath))
$readmePath = $readmePath.Replace("\", "/")
dotnet run --project .\harp_devices_src\harp.schemaprocessor $file .\harp_devices_spec $readmePath
Expand Down
2 changes: 1 addition & 1 deletion docs/harp_devices_src/harp.device.treadmill
54 changes: 54 additions & 0 deletions docs/workflows/SaveHarpDataWithMetadata.bonsai
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?xml version="1.0" encoding="utf-8"?>
<WorkflowBuilder Version="2.8.5"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p1="clr-namespace:AllenNeuralDynamics.LicketySplit;assembly=AllenNeuralDynamics.LicketySplit"
xmlns:harp="clr-namespace:Bonsai.Harp;assembly=Bonsai.Harp"
xmlns:rx="clr-namespace:Bonsai.Reactive;assembly=Bonsai.Core"
xmlns="https://bonsai-rx.org/2018/workflow">
<Workflow>
<Nodes>
<Expression xsi:type="IncludeWorkflow" Path="AllenNeuralDynamics.Core:GenerateRootLoggingPath.bonsai">
<RootFolder xsi:nil="true" />
<Subject xsi:nil="true" />
<DateTimeOffset>0001-01-01T00:00:00.0000000+00:00</DateTimeOffset>
<SubjectName>LoggingRootPath</SubjectName>
</Expression>
<Expression xsi:type="Combinator">
<Combinator xsi:type="p1:Device">
<harp:OperationMode>Active</harp:OperationMode>
<harp:OperationLed>On</harp:OperationLed>
<harp:DumpRegisters>true</harp:DumpRegisters>
<harp:VisualIndicators>On</harp:VisualIndicators>
<harp:Heartbeat>Disabled</harp:Heartbeat>
<harp:IgnoreErrors>false</harp:IgnoreErrors>
<harp:PortName>COMx</harp:PortName>
</Combinator>
</Expression>
<Expression xsi:type="rx:PublishSubject">
<Name>LicketySplitEvents</Name>
</Expression>
<Expression xsi:type="SubscribeSubject">
<Name>LicketySplitEvents</Name>
</Expression>
<Expression xsi:type="Combinator">
<Combinator xsi:type="p1:GetMetadata" />
</Expression>
<Expression xsi:type="PropertyMapping">
<PropertyMappings>
<Property Name="DeviceMetadata" />
</PropertyMappings>
</Expression>
<Expression xsi:type="IncludeWorkflow" Path="AllenNeuralDynamics.Core:LogHarpDeviceWithMetadata.bonsai">
<DeviceMetadata />
<Modality>Behavior</Modality>
<DeviceName>Lickometer</DeviceName>
</Expression>
</Nodes>
<Edges>
<Edge From="1" To="2" Label="Source1" />
<Edge From="3" To="6" Label="Source1" />
<Edge From="4" To="5" Label="Source1" />
<Edge From="5" To="6" Label="Source2" />
</Edges>
</Workflow>
</WorkflowBuilder>
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<PackageTags>Bonsai Rx Core AllenNeuralDynamics</PackageTags>
<TargetFramework>net472</TargetFramework>
<Features>strict</Features>
<Version>0.2.7</Version>
<Version>0.2.8</Version>
</PropertyGroup>

<ItemGroup>
Expand Down
4 changes: 2 additions & 2 deletions src/AllenNeuralDynamics.Core/FfmpegVideoWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,11 @@ public class FfmpegVideoWriter : Sink<IplImage>

[Editor(DesignTypes.MultilineStringEditor, DesignTypes.UITypeEditor)]
[Description("The optional set of command-line arguments to use for configuring the video codec.")]
public string OutputArguments { get; set; } = @"-vf ""scale=out_color_matrix=bt709:out_range=full"" -c:v h264_nvenc -pix_fmt nv12 -color_range full -colorspace bt709 -color_trc linear -tune hq -preset p4 -rc vbr -cq 12 -b:v 0M -maxrate 700M -bufsize 350M";
public string OutputArguments { get; set; } = @"-vf ""scale=out_color_matrix=bt709:out_range=full"" -c:v h264_nvenc -pix_fmt nv12 -color_range full -colorspace bt709 -color_trc linear -tune hq -preset p4 -rc vbr -cq 12 -b:v 0M -metadata author=""Allen Institute for Neural Dynamics"" -maxrate 700M -bufsize 350M";

[Editor(DesignTypes.MultilineStringEditor, DesignTypes.UITypeEditor)]
[Description("The optional set of command-line arguments to use for configuring the input video stream.")]
public string InputArguments { get; set; } = "-colorspace rgb -color_primaries bt709 -color_trc linear";
public string InputArguments { get; set; } = "-colorspace bt709 -color_primaries bt709 -color_range full -color_trc linear";

public override IObservable<IplImage> Process(IObservable<IplImage> source)
{
Expand Down
185 changes: 185 additions & 0 deletions src/AllenNeuralDynamics.Core/LogHarpDeviceWithMetadata.bonsai
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
<?xml version="1.0" encoding="utf-8"?>
<WorkflowBuilder Version="2.8.5"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:harp="clr-namespace:Bonsai.Harp;assembly=Bonsai.Harp"
xmlns:rx="clr-namespace:Bonsai.Reactive;assembly=Bonsai.Core"
xmlns:p1="clr-namespace:AllenNeuralDynamics.Core;assembly=AllenNeuralDynamics.Core"
xmlns:scr="clr-namespace:Bonsai.Scripting.Expressions;assembly=Bonsai.Scripting.Expressions"
xmlns:io="clr-namespace:Bonsai.IO;assembly=Bonsai.System"
xmlns="https://bonsai-rx.org/2018/workflow">
<Workflow>
<Nodes>
<Expression xsi:type="WorkflowInput" TypeArguments="harp:HarpMessage">
<Name>Source1</Name>
</Expression>
<Expression xsi:type="ExternalizedMapping">
<Property Name="DeviceMetadata" />
<Property Name="Modality" />
<Property Name="DeviceName" />
</Expression>
<Expression xsi:type="rx:Defer">
<Name>LogHarpDeviceWithMetadata</Name>
<Workflow>
<Nodes>
<Expression xsi:type="WorkflowInput" TypeArguments="harp:HarpMessage">
<Name>Source1</Name>
</Expression>
<Expression xsi:type="Combinator">
<Combinator xsi:type="harp:GroupByRegister" />
</Expression>
<Expression xsi:type="SubscribeSubject">
<Name>PathConstructor</Name>
</Expression>
<Expression xsi:type="Format">
<Format>{0}/{1}.harp/{2}.bin</Format>
<Selector>Item1,Item2.DeviceName,Item2.HarpDeviceName</Selector>
</Expression>
<Expression xsi:type="PropertyMapping">
<PropertyMappings>
<Property Name="FileName" />
</PropertyMappings>
</Expression>
<Expression xsi:type="Combinator">
<Combinator xsi:type="harp:MessageWriter">
<harp:FileName>//_20240705T174448\behavior/.harp/.bin</harp:FileName>
<harp:Suffix>None</harp:Suffix>
<harp:Buffered>true</harp:Buffered>
<harp:Overwrite>false</harp:Overwrite>
<harp:FilterType>Include</harp:FilterType>
<harp:MessageType xsi:nil="true" />
</Combinator>
</Expression>
<Expression xsi:type="WorkflowOutput" />
<Expression xsi:type="ExternalizedMapping">
<Property Name="Value" DisplayName="DeviceMetadata" />
</Expression>
<Expression xsi:type="Combinator">
<Combinator xsi:type="StringProperty">
<Value />
</Combinator>
</Expression>
<Expression xsi:type="Combinator">
<Combinator xsi:type="rx:Take">
<rx:Count>1</rx:Count>
</Combinator>
</Expression>
<Expression xsi:type="rx:AsyncSubject">
<Name>DeviceMetadata</Name>
</Expression>
<Expression xsi:type="ExternalizedMapping">
<Property Name="Name" DisplayName="SubjectName" />
</Expression>
<Expression xsi:type="SubscribeSubject">
<Name>LoggingRootPath</Name>
</Expression>
<Expression xsi:type="ExternalizedMapping">
<Property Name="Modality" />
</Expression>
<Expression xsi:type="Combinator">
<Combinator xsi:type="p1:AppendModalitySuffix">
<p1:Modality>Behavior</p1:Modality>
</Combinator>
</Expression>
<Expression xsi:type="ExternalizedMapping">
<Property Name="Value" DisplayName="DeviceName" />
</Expression>
<Expression xsi:type="Combinator">
<Combinator xsi:type="StringProperty">
<Value />
</Combinator>
</Expression>
<Expression xsi:type="SubscribeSubject">
<Name>DeviceMetadata</Name>
</Expression>
<Expression xsi:type="Combinator">
<Combinator xsi:type="rx:Take">
<rx:Count>1</rx:Count>
</Combinator>
</Expression>
<Expression xsi:type="Parse">
<Pattern>device: %swhoAmI</Pattern>
</Expression>
<Expression xsi:type="scr:ExpressionTransform">
<scr:Name>Trim</scr:Name>
<scr:Expression>it.Trim()</scr:Expression>
</Expression>
<Expression xsi:type="Combinator">
<Combinator xsi:type="rx:Zip" />
</Expression>
<Expression xsi:type="scr:ExpressionTransform">
<scr:Name>Rename</scr:Name>
<scr:Expression>new(Item1 as DeviceName, Item2 as HarpDeviceName)</scr:Expression>
</Expression>
<Expression xsi:type="Combinator">
<Combinator xsi:type="rx:Zip" />
</Expression>
<Expression xsi:type="Combinator">
<Combinator xsi:type="rx:Take">
<rx:Count>1</rx:Count>
</Combinator>
</Expression>
<Expression xsi:type="rx:AsyncSubject">
<Name>PathConstructor</Name>
</Expression>
<Expression xsi:type="SubscribeSubject">
<Name>DeviceMetadata</Name>
</Expression>
<Expression xsi:type="SubscribeSubject">
<Name>PathConstructor</Name>
</Expression>
<Expression xsi:type="Format">
<Format>{0}/{1}.harp/device.yml</Format>
<Selector>Item1,Item2.DeviceName</Selector>
</Expression>
<Expression xsi:type="PropertyMapping">
<PropertyMappings>
<Property Name="Path" />
</PropertyMappings>
</Expression>
<Expression xsi:type="Combinator">
<Combinator xsi:type="io:WriteAllText">
<io:Overwrite>false</io:Overwrite>
<io:Append>false</io:Append>
</Combinator>
</Expression>
</Nodes>
<Edges>
<Edge From="0" To="1" Label="Source1" />
<Edge From="1" To="5" Label="Source1" />
<Edge From="2" To="3" Label="Source1" />
<Edge From="3" To="4" Label="Source1" />
<Edge From="4" To="5" Label="Source2" />
<Edge From="5" To="6" Label="Source1" />
<Edge From="7" To="8" Label="Source1" />
<Edge From="8" To="9" Label="Source1" />
<Edge From="9" To="10" Label="Source1" />
<Edge From="11" To="12" Label="Source1" />
<Edge From="12" To="14" Label="Source1" />
<Edge From="13" To="14" Label="Source2" />
<Edge From="14" To="23" Label="Source1" />
<Edge From="15" To="16" Label="Source1" />
<Edge From="16" To="21" Label="Source1" />
<Edge From="17" To="18" Label="Source1" />
<Edge From="18" To="19" Label="Source1" />
<Edge From="19" To="20" Label="Source1" />
<Edge From="20" To="21" Label="Source2" />
<Edge From="21" To="22" Label="Source1" />
<Edge From="22" To="23" Label="Source2" />
<Edge From="23" To="24" Label="Source1" />
<Edge From="24" To="25" Label="Source1" />
<Edge From="26" To="30" Label="Source1" />
<Edge From="27" To="28" Label="Source1" />
<Edge From="28" To="29" Label="Source1" />
<Edge From="29" To="30" Label="Source2" />
</Edges>
</Workflow>
</Expression>
<Expression xsi:type="WorkflowOutput" />
</Nodes>
<Edges>
<Edge From="0" To="2" Label="Source1" />
<Edge From="1" To="2" Label="Source2" />
<Edge From="2" To="3" Label="Source1" />
</Edges>
</Workflow>
</WorkflowBuilder>
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<PackageTags>Bonsai Rx Core AllenNeuralDynamics</PackageTags>
<TargetFramework>net472</TargetFramework>
<Features>strict</Features>
<Version>0.1.8</Version>
<Version>0.1.9</Version>
</PropertyGroup>

<ItemGroup>
Expand Down
14 changes: 4 additions & 10 deletions src/AllenNeuralDynamics.HarpUtils/HarpAnalogInputDevice.bonsai
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<WorkflowBuilder Version="2.8.4+2bab12753e452fa02540eb20e93664d41b112590"
<WorkflowBuilder Version="2.8.5"
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"
Expand Down Expand Up @@ -29,10 +29,10 @@
</Expression>
<Expression xsi:type="WorkflowOutput" />
<Expression xsi:type="ExternalizedMapping">
<Property Name="Name" DisplayName="StartExperimentSubjectName" />
<Property Name="Name" DisplayName="TriggerHarpReadDumpSubjectName" />
</Expression>
<Expression xsi:type="SubscribeSubject">
<Name>StartExperiment</Name>
<Name>TriggerHarpReadDump</Name>
</Expression>
<Expression xsi:type="harp:CreateMessage">
<harp:MessageType>Write</harp:MessageType>
Expand All @@ -45,11 +45,6 @@
<harp:Heartbeat>Enabled</harp:Heartbeat>
</harp:Payload>
</Expression>
<Expression xsi:type="Combinator">
<Combinator xsi:type="rx:Take">
<rx:Count>1</rx:Count>
</Combinator>
</Expression>
<Expression xsi:type="MulticastSubject">
<Name>HarpAnalogInputCommands</Name>
</Expression>
Expand Down Expand Up @@ -106,7 +101,7 @@
<Edge From="5" To="6" Label="Source1" />
<Edge From="6" To="7" Label="Source1" />
<Edge From="7" To="8" Label="Source1" />
<Edge From="8" To="9" Label="Source1" />
<Edge From="9" To="10" Label="Source1" />
<Edge From="10" To="11" Label="Source1" />
<Edge From="11" To="12" Label="Source1" />
<Edge From="12" To="13" Label="Source1" />
Expand All @@ -115,7 +110,6 @@
<Edge From="15" To="16" Label="Source1" />
<Edge From="16" To="17" Label="Source1" />
<Edge From="17" To="18" Label="Source1" />
<Edge From="18" To="19" Label="Source1" />
</Edges>
</Workflow>
</WorkflowBuilder>
Loading

0 comments on commit 7aac10b

Please sign in to comment.