From bc02b1f95ee50688883e964f93ee8884f014065c Mon Sep 17 00:00:00 2001 From: bruno-f-cruz <7049351+bruno-f-cruz@users.noreply.github.com> Date: Sat, 9 Nov 2024 09:48:53 -0800 Subject: [PATCH 1/9] Add operator to log harp data with device.yml metadata --- .../LogHarpDeviceWithMetadata.bonsai | 185 ++++++++++++++++++ 1 file changed, 185 insertions(+) create mode 100644 src/AllenNeuralDynamics.Core/LogHarpDeviceWithMetadata.bonsai diff --git a/src/AllenNeuralDynamics.Core/LogHarpDeviceWithMetadata.bonsai b/src/AllenNeuralDynamics.Core/LogHarpDeviceWithMetadata.bonsai new file mode 100644 index 0000000..3d07bf9 --- /dev/null +++ b/src/AllenNeuralDynamics.Core/LogHarpDeviceWithMetadata.bonsai @@ -0,0 +1,185 @@ + + + + + + Source1 + + + + + + + + LogHarpDeviceWithMetadata + + + + Source1 + + + + + + PathConstructor + + + {0}/{1}.harp/{2}.bin + Item1,Item2.DeviceName,Item2.HarpDeviceName + + + + + + + + + //_20240705T174448\behavior/.harp/.bin + None + true + false + Include + + + + + + + + + + + + + + + 1 + + + + DeviceMetadata + + + + + + LoggingRootPath + + + + + + + Behavior + + + + + + + + + + + + DeviceMetadata + + + + 1 + + + + device: %swhoAmI + + + Trim + it.Trim() + + + + + + Rename + new(Item1 as DeviceName, Item2 as HarpDeviceName) + + + + + + + 1 + + + + PathConstructor + + + DeviceMetadata + + + PathConstructor + + + {0}/{1}.harp/device.yml + Item1,Item2.DeviceName + + + + + + + + + false + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 080323ba942b2da763bc177b0c681322121b0bdc Mon Sep 17 00:00:00 2001 From: bruno-f-cruz <7049351+bruno-f-cruz@users.noreply.github.com> Date: Sat, 9 Nov 2024 11:04:47 -0800 Subject: [PATCH 2/9] Document harp logging pattern with metadata --- docs/articles/core-logging.md | 10 ++++ .../workflows/SaveHarpDataWithMetadata.bonsai | 54 +++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 docs/workflows/SaveHarpDataWithMetadata.bonsai diff --git a/docs/articles/core-logging.md b/docs/articles/core-logging.md index 4ef1ebf..f3730c5 100644 --- a/docs/articles/core-logging.md +++ b/docs/articles/core-logging.md @@ -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`: diff --git a/docs/workflows/SaveHarpDataWithMetadata.bonsai b/docs/workflows/SaveHarpDataWithMetadata.bonsai new file mode 100644 index 0000000..5f37ed1 --- /dev/null +++ b/docs/workflows/SaveHarpDataWithMetadata.bonsai @@ -0,0 +1,54 @@ + + + + + + + + 0001-01-01T00:00:00.0000000+00:00 + LoggingRootPath + + + + Active + On + true + On + Disabled + false + COMx + + + + LicketySplitEvents + + + LicketySplitEvents + + + + + + + + + + + + Behavior + Lickometer + + + + + + + + + + \ No newline at end of file From 3813a0f9d0cafab9f9d930cb8a6deb6183e87740 Mon Sep 17 00:00:00 2001 From: bruno-f-cruz <7049351+bruno-f-cruz@users.noreply.github.com> Date: Sat, 9 Nov 2024 11:04:55 -0800 Subject: [PATCH 3/9] Bump package version --- src/AllenNeuralDynamics.Core/AllenNeuralDynamics.Core.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/AllenNeuralDynamics.Core/AllenNeuralDynamics.Core.csproj b/src/AllenNeuralDynamics.Core/AllenNeuralDynamics.Core.csproj index e8451fd..7c0735f 100644 --- a/src/AllenNeuralDynamics.Core/AllenNeuralDynamics.Core.csproj +++ b/src/AllenNeuralDynamics.Core/AllenNeuralDynamics.Core.csproj @@ -9,7 +9,7 @@ Bonsai Rx Core AllenNeuralDynamics net472 strict - 0.2.7 + 0.2.8 From e4da8af017e9b5a5e2f5667b5ccf60e4ef803bb5 Mon Sep 17 00:00:00 2001 From: bruno-f-cruz <7049351+bruno-f-cruz@users.noreply.github.com> Date: Sat, 9 Nov 2024 11:09:13 -0800 Subject: [PATCH 4/9] Update ffmpeg string --- src/AllenNeuralDynamics.Core/FfmpegVideoWriter.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/AllenNeuralDynamics.Core/FfmpegVideoWriter.cs b/src/AllenNeuralDynamics.Core/FfmpegVideoWriter.cs index c0b02d9..0cad6d6 100644 --- a/src/AllenNeuralDynamics.Core/FfmpegVideoWriter.cs +++ b/src/AllenNeuralDynamics.Core/FfmpegVideoWriter.cs @@ -29,11 +29,11 @@ public class FfmpegVideoWriter : Sink [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 Process(IObservable source) { From 0d4ab03a9815f9f05a6a696ab7ec986140d141c2 Mon Sep 17 00:00:00 2001 From: bruno-f-cruz <7049351+bruno-f-cruz@users.noreply.github.com> Date: Mon, 11 Nov 2024 12:59:15 -0800 Subject: [PATCH 5/9] Add operator to validate harp clock synchronization output --- .../ValidateClkOutputChannels.cs | 70 +++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 src/AllenNeuralDynamics.HarpUtils/ValidateClkOutputChannels.cs diff --git a/src/AllenNeuralDynamics.HarpUtils/ValidateClkOutputChannels.cs b/src/AllenNeuralDynamics.HarpUtils/ValidateClkOutputChannels.cs new file mode 100644 index 0000000..b653ff2 --- /dev/null +++ b/src/AllenNeuralDynamics.HarpUtils/ValidateClkOutputChannels.cs @@ -0,0 +1,70 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reactive.Linq; +using Bonsai; +using System.ComponentModel; +using Bonsai.Harp; +using System.Xml.Serialization; + +namespace AllenNeuralDynamics.HarpUtils +{ + [Combinator] + [WorkflowElementCategory(ElementCategory.Transform)] + [Description("From a dictionary of expected channels connected to a clock synchronizer, outputs a structure with diagnosis information.")] + public class ValidateClkOutputChannels + { + [XmlIgnore] + [Description("Paired elements of the channel number and channel name.")] + + public Dictionary ExpectedChannels { get; set; } = new Dictionary(); + + + public IObservable Process(IObservable source) where T : struct, IConvertible{ + return Process(source.Select(value => Convert.ToInt32(value))); + } + + public IObservable Process(IObservable source){ + + return source.Select(value => { + var expectedChannelsMask = ExpectedChannelsMask(ExpectedChannels); + var foundChannels = expectedChannelsMask & value; + + return new ValidateClkOutputChannelsDiagnosis{ + ExtraChannels = Enumerable.Range(0, 32).Where(bit => ((~expectedChannelsMask & value) & (1 << bit)) != 0).ToArray(), + FoundChannels = FilterDictionaryOnMask(ExpectedChannels, foundChannels), + MissingChannels = FilterDictionaryOnMask(ExpectedChannels, ~foundChannels), + }; + }); + } + + private static Dictionary FilterDictionaryOnMask(Dictionary dictionary, int mask) { + return dictionary.Where(channel => (mask & (1 << channel.Key)) != 0).ToDictionary(channel => channel.Key, channel => channel.Value); + } + + private static int ExpectedChannelsMask(Dictionary expectedChannels) { + int mask = 0; + foreach (var channel in expectedChannels) { + mask |= 1 << channel.Key; + } + return mask; + } + } + + public class ValidateClkOutputChannelsDiagnosis + { + public Dictionary FoundChannels; + public int[] ExtraChannels; + public Dictionary MissingChannels; + + + public override string ToString() + { + return $"Found channels: {string.Join(", ", FoundChannels.Select(channel => $"{channel.Key} ({channel.Value})"))}\n" + + $"Extra channels: {string.Join(", ", ExtraChannels)}\n" + + $"Missing channels: {string.Join(", ", MissingChannels.Select(channel => $"{channel.Key} ({channel.Value})"))}"; + } + } + + +} From 045ae14720edd61ab12363988389997b3cd041e5 Mon Sep 17 00:00:00 2001 From: bruno-f-cruz <7049351+bruno-f-cruz@users.noreply.github.com> Date: Mon, 11 Nov 2024 12:59:33 -0800 Subject: [PATCH 6/9] Decouple reading dump request from start of experiment --- .../HarpAnalogInputDevice.bonsai | 14 +++----- .../HarpBehaviorDevice.bonsai | 14 +++----- .../HarpLicketySplitDevice.bonsai | 12 ++----- .../HarpOlfactometerDevice.bonsai | 34 ++++++++----------- .../HarpSniffDetector.bonsai | 14 +++----- .../HarpTimestampGeneratorGen3Device.bonsai | 12 ++----- .../HarpTreadmill.bonsai | 12 ++----- 7 files changed, 35 insertions(+), 77 deletions(-) diff --git a/src/AllenNeuralDynamics.HarpUtils/HarpAnalogInputDevice.bonsai b/src/AllenNeuralDynamics.HarpUtils/HarpAnalogInputDevice.bonsai index dc5d477..b656929 100644 --- a/src/AllenNeuralDynamics.HarpUtils/HarpAnalogInputDevice.bonsai +++ b/src/AllenNeuralDynamics.HarpUtils/HarpAnalogInputDevice.bonsai @@ -1,5 +1,5 @@  - - + - StartExperiment + TriggerHarpReadDump Write @@ -45,11 +45,6 @@ Enabled - - - 1 - - HarpAnalogInputCommands @@ -106,7 +101,7 @@ - + @@ -115,7 +110,6 @@ - \ No newline at end of file diff --git a/src/AllenNeuralDynamics.HarpUtils/HarpBehaviorDevice.bonsai b/src/AllenNeuralDynamics.HarpUtils/HarpBehaviorDevice.bonsai index d061668..ce460de 100644 --- a/src/AllenNeuralDynamics.HarpUtils/HarpBehaviorDevice.bonsai +++ b/src/AllenNeuralDynamics.HarpUtils/HarpBehaviorDevice.bonsai @@ -1,5 +1,5 @@  - - + - StartExperiment + TriggerHarpReadDump Write @@ -45,11 +45,6 @@ Enabled - - - 1 - - HarpBehaviorCommands @@ -79,10 +74,9 @@ - + - \ No newline at end of file diff --git a/src/AllenNeuralDynamics.HarpUtils/HarpLicketySplitDevice.bonsai b/src/AllenNeuralDynamics.HarpUtils/HarpLicketySplitDevice.bonsai index aee0e04..88ceca0 100644 --- a/src/AllenNeuralDynamics.HarpUtils/HarpLicketySplitDevice.bonsai +++ b/src/AllenNeuralDynamics.HarpUtils/HarpLicketySplitDevice.bonsai @@ -1,5 +1,5 @@  - - + - StartExperiment + TriggerHarpReadDump Write @@ -45,11 +45,6 @@ Enabled - - - 1 - - HarpLickometerCommands @@ -62,7 +57,6 @@ - \ No newline at end of file diff --git a/src/AllenNeuralDynamics.HarpUtils/HarpOlfactometerDevice.bonsai b/src/AllenNeuralDynamics.HarpUtils/HarpOlfactometerDevice.bonsai index 58089f8..9092a2f 100644 --- a/src/AllenNeuralDynamics.HarpUtils/HarpOlfactometerDevice.bonsai +++ b/src/AllenNeuralDynamics.HarpUtils/HarpOlfactometerDevice.bonsai @@ -1,5 +1,5 @@  -On Enabled false - COM6 + @@ -29,10 +29,10 @@ - + - StartExperiment + TriggerHarpReadDump Write @@ -45,11 +45,6 @@ Enabled - - - 1 - - HarpOlfactometerCommands @@ -153,25 +148,24 @@ - - - + + + + - - - + + - - - - + + + + - \ No newline at end of file diff --git a/src/AllenNeuralDynamics.HarpUtils/HarpSniffDetector.bonsai b/src/AllenNeuralDynamics.HarpUtils/HarpSniffDetector.bonsai index 773ef85..0d698a8 100644 --- a/src/AllenNeuralDynamics.HarpUtils/HarpSniffDetector.bonsai +++ b/src/AllenNeuralDynamics.HarpUtils/HarpSniffDetector.bonsai @@ -1,5 +1,5 @@  -HarpSniffDetectorEvents - + - StartExperiment - - - - 1 - + TriggerHarpReadDump Write @@ -77,10 +72,9 @@ - + - \ No newline at end of file diff --git a/src/AllenNeuralDynamics.HarpUtils/HarpTimestampGeneratorGen3Device.bonsai b/src/AllenNeuralDynamics.HarpUtils/HarpTimestampGeneratorGen3Device.bonsai index 6a7631a..80cda63 100644 --- a/src/AllenNeuralDynamics.HarpUtils/HarpTimestampGeneratorGen3Device.bonsai +++ b/src/AllenNeuralDynamics.HarpUtils/HarpTimestampGeneratorGen3Device.bonsai @@ -1,5 +1,5 @@  - - + - StartExperiment + TriggerHarpReadDump Write @@ -45,11 +45,6 @@ Enabled - - - 1 - - HarpClockGenCommands @@ -62,7 +57,6 @@ - \ No newline at end of file diff --git a/src/AllenNeuralDynamics.HarpUtils/HarpTreadmill.bonsai b/src/AllenNeuralDynamics.HarpUtils/HarpTreadmill.bonsai index 83222f5..45a6dd8 100644 --- a/src/AllenNeuralDynamics.HarpUtils/HarpTreadmill.bonsai +++ b/src/AllenNeuralDynamics.HarpUtils/HarpTreadmill.bonsai @@ -29,10 +29,10 @@ - + - StartExperiment + TriggerHarpReadDump Write @@ -45,11 +45,6 @@ Enabled - - - 1 - - HarpTreadmillCommands @@ -93,13 +88,12 @@ - + - \ No newline at end of file From 9dfa5c7e0d83b597b94544995ca5cbc6f78a4ead Mon Sep 17 00:00:00 2001 From: bruno-f-cruz <7049351+bruno-f-cruz@users.noreply.github.com> Date: Mon, 11 Nov 2024 13:12:36 -0800 Subject: [PATCH 7/9] Bump package for release --- .../AllenNeuralDynamics.HarpUtils.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/AllenNeuralDynamics.HarpUtils/AllenNeuralDynamics.HarpUtils.csproj b/src/AllenNeuralDynamics.HarpUtils/AllenNeuralDynamics.HarpUtils.csproj index 14e9338..be52362 100644 --- a/src/AllenNeuralDynamics.HarpUtils/AllenNeuralDynamics.HarpUtils.csproj +++ b/src/AllenNeuralDynamics.HarpUtils/AllenNeuralDynamics.HarpUtils.csproj @@ -9,7 +9,7 @@ Bonsai Rx Core AllenNeuralDynamics net472 strict - 0.1.8 + 0.1.9 From 62f24b14a850feace42d50140daed8d41ff09fcd Mon Sep 17 00:00:00 2001 From: bruno-f-cruz <7049351+bruno-f-cruz@users.noreply.github.com> Date: Mon, 11 Nov 2024 14:41:40 -0800 Subject: [PATCH 8/9] Update harp devices submodules --- docs/harp_devices_src/harp.device.cuttlefish | 2 +- docs/harp_devices_src/harp.device.environment-sensor | 2 +- docs/harp_devices_src/harp.device.lickety-split | 2 +- docs/harp_devices_src/harp.device.sniff-detector | 2 +- docs/harp_devices_src/harp.device.treadmill | 2 +- docs/harp_devices_src/harp.device.white-rabbit | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/harp_devices_src/harp.device.cuttlefish b/docs/harp_devices_src/harp.device.cuttlefish index 662229d..09bc687 160000 --- a/docs/harp_devices_src/harp.device.cuttlefish +++ b/docs/harp_devices_src/harp.device.cuttlefish @@ -1 +1 @@ -Subproject commit 662229de3f8a03d10de4451d42bd9b94c628d42b +Subproject commit 09bc68768468b2c474bda220b4d65752d3600e3c diff --git a/docs/harp_devices_src/harp.device.environment-sensor b/docs/harp_devices_src/harp.device.environment-sensor index 3731b52..3331663 160000 --- a/docs/harp_devices_src/harp.device.environment-sensor +++ b/docs/harp_devices_src/harp.device.environment-sensor @@ -1 +1 @@ -Subproject commit 3731b52cd205fef7bf0eb32605e858b6b24ffe4d +Subproject commit 3331663993498bb7071e55e4a56a2f6dd43026ed diff --git a/docs/harp_devices_src/harp.device.lickety-split b/docs/harp_devices_src/harp.device.lickety-split index 401c5a0..62e7257 160000 --- a/docs/harp_devices_src/harp.device.lickety-split +++ b/docs/harp_devices_src/harp.device.lickety-split @@ -1 +1 @@ -Subproject commit 401c5a0bf38660eecbc065f6dc2be4cf5dde58cd +Subproject commit 62e7257f3488f07f02e597a00ab3f20fc84fa61a diff --git a/docs/harp_devices_src/harp.device.sniff-detector b/docs/harp_devices_src/harp.device.sniff-detector index 50ba549..cc5b839 160000 --- a/docs/harp_devices_src/harp.device.sniff-detector +++ b/docs/harp_devices_src/harp.device.sniff-detector @@ -1 +1 @@ -Subproject commit 50ba54952a9bd17b212373be38d86f41b3e25c61 +Subproject commit cc5b8390f04df638eb9b0d8b59309c12b6c7e4ea diff --git a/docs/harp_devices_src/harp.device.treadmill b/docs/harp_devices_src/harp.device.treadmill index efe3f02..b148f47 160000 --- a/docs/harp_devices_src/harp.device.treadmill +++ b/docs/harp_devices_src/harp.device.treadmill @@ -1 +1 @@ -Subproject commit efe3f02fa678d25742be7cf65743ffb5ab4beefb +Subproject commit b148f477c36a977078db4dbb38d85b3faa50e0c2 diff --git a/docs/harp_devices_src/harp.device.white-rabbit b/docs/harp_devices_src/harp.device.white-rabbit index 2954fdc..f891477 160000 --- a/docs/harp_devices_src/harp.device.white-rabbit +++ b/docs/harp_devices_src/harp.device.white-rabbit @@ -1 +1 @@ -Subproject commit 2954fdc927357b1a078ef784c3663631b819c645 +Subproject commit f891477459c17dfc0235c19b32d7b1e809054893 From 69b9c5a7857ccb053bd008ece9cddba007668ef4 Mon Sep 17 00:00:00 2001 From: bruno-f-cruz <7049351+bruno-f-cruz@users.noreply.github.com> Date: Mon, 11 Nov 2024 14:48:29 -0800 Subject: [PATCH 9/9] Default to find device.yml in repository root --- docs/build.ps1 | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/docs/build.ps1 b/docs/build.ps1 index 2868cf0..b343170 100644 --- a/docs/build.ps1 +++ b/docs/build.ps1 @@ -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