diff --git a/.bonsai/Bonsai.config b/.bonsai/Bonsai.config new file mode 100644 index 0000000..ac40c8a --- /dev/null +++ b/.bonsai/Bonsai.config @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/bonsai/NuGet.Config b/.bonsai/NuGet.config similarity index 69% rename from bonsai/NuGet.Config rename to .bonsai/NuGet.config index 81b34d6..97e8b73 100644 --- a/bonsai/NuGet.Config +++ b/.bonsai/NuGet.config @@ -4,7 +4,5 @@ - - diff --git a/.bonsai/Setup.cmd b/.bonsai/Setup.cmd new file mode 100644 index 0000000..92d983d --- /dev/null +++ b/.bonsai/Setup.cmd @@ -0,0 +1,4 @@ +@echo off +pushd %~dp0 +powershell -ExecutionPolicy Bypass -File ./Setup.ps1 +popd \ No newline at end of file diff --git a/.bonsai/Setup.ps1 b/.bonsai/Setup.ps1 new file mode 100644 index 0000000..01cfba6 --- /dev/null +++ b/.bonsai/Setup.ps1 @@ -0,0 +1,21 @@ +Push-Location $PSScriptRoot +if (!(Test-Path "./Bonsai.exe")) { + $release = "https://github.com/bonsai-rx/bonsai/releases/latest/download/Bonsai.zip" + $configPath = "./Bonsai.config" + if (Test-Path $configPath) { + [xml]$config = Get-Content $configPath + $bootstrapper = $config.PackageConfiguration.Packages.Package.where{$_.id -eq 'Bonsai'} + if ($bootstrapper) { + $version = $bootstrapper.version + $release = "https://github.com/bonsai-rx/bonsai/releases/download/$version/Bonsai.zip" + } + } + Invoke-WebRequest $release -OutFile "temp.zip" + Move-Item -Path "NuGet.config" "temp.config" -ErrorAction SilentlyContinue + Expand-Archive "temp.zip" -DestinationPath "." -Force + Move-Item -Path "temp.config" "NuGet.config" -Force -ErrorAction SilentlyContinue + Remove-Item -Path "temp.zip" + Remove-Item -Path "Bonsai32.exe" +} +& .\Bonsai.exe --no-editor +Pop-Location \ No newline at end of file diff --git a/src/.editorconfig b/.editorconfig similarity index 100% rename from src/.editorconfig rename to .editorconfig diff --git a/.github/workflows/ci-audit.yml b/.github/workflows/ci-audit.yml index cf6d2ed..a4f6e74 100644 --- a/.github/workflows/ci-audit.yml +++ b/.github/workflows/ci-audit.yml @@ -6,28 +6,39 @@ on: pull_request: branches: [ main ] workflow_dispatch: - +env: + DOTNET_NOLOGO: true + DOTNET_CLI_TELEMETRY_OPTOUT: true + DOTNET_GENERATE_ASPNET_CERTIFICATE: false + ContinuousIntegrationBuild: true jobs: audit: - runs-on: windows-latest + strategy: + fail-fast: false + matrix: + configuration: [debug, release] + os: [ubuntu-latest, windows-latest] + include: + - os: ubuntu-latest + test-filter: --filter TestCategory!=DriverDependent + runs-on: ${{ matrix.os }} steps: - name: Checkout - uses: actions/checkout@v2.3.4 - - - name: Setup MSBuild - uses: microsoft/setup-msbuild@v1 + uses: actions/checkout@v4 - - name: Setup VSTest - uses: darenm/Setup-VSTest@v1 - - - name: Setup NuGet - uses: NuGet/setup-nuget@v1.0.5 + - name: Setup .NET + uses: actions/setup-dotnet@v4 + with: + dotnet-version: 8.x - - name: Restore NuGet Packages - run: nuget restore src/Aeon.sln + - name: Restore + run: dotnet restore - - name: Build Project - run: msbuild src/Aeon.sln /p:Configuration=Release + - name: Build + run: dotnet build --no-restore --configuration ${{ matrix.configuration }} + + - name: Pack + run: dotnet pack --no-build --configuration ${{ matrix.configuration }} - - name: Run Tests - run: vstest.console.exe src/Aeon.Tests/bin/Release/net472/Aeon.Tests.dll \ No newline at end of file + - name: Test + run: dotnet test --no-build --configuration ${{ matrix.configuration }} ${{ matrix.test-filter }} \ No newline at end of file diff --git a/.gitignore b/.gitignore index 613d6c8..f331238 100644 --- a/.gitignore +++ b/.gitignore @@ -1,23 +1,5 @@ -# State recovery files -~* - -# Bonsai scripting and environment files -.vs -bin -obj -Packages -*.bin -*.avi -*.dll -*.exe -*.exe.settings -SessionSummary - -# Byte-compiled / optimized / DLL files -__pycache__/ -*.py[cod] -*$py.class - -# Environments -.venv -winpython \ No newline at end of file +.vs/ +/artifacts/ +.bonsai/Packages/ +.bonsai/*.exe +.bonsai/*.exe.settings diff --git a/src/Aeon.sln b/Aeon.sln similarity index 59% rename from src/Aeon.sln rename to Aeon.sln index 4e5c260..0135b79 100644 --- a/src/Aeon.sln +++ b/Aeon.sln @@ -3,9 +3,9 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.3.32825.248 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Aeon.Acquisition", "Aeon.Acquisition\Aeon.Acquisition.csproj", "{5F8F4AF8-7C4C-436F-A74E-4BE82A4526F6}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Aeon.Acquisition", "src\Aeon.Acquisition\Aeon.Acquisition.csproj", "{5F8F4AF8-7C4C-436F-A74E-4BE82A4526F6}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Aeon.Tests", "Aeon.Tests\Aeon.Tests.csproj", "{235C151D-1507-4EDA-8BE9-79FA24EE858E}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Aeon.Tests", "src\Aeon.Tests\Aeon.Tests.csproj", "{235C151D-1507-4EDA-8BE9-79FA24EE858E}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{FB666352-C351-407B-9BF6-AA5DDC6C9DD5}" ProjectSection(SolutionItems) = preProject @@ -14,11 +14,17 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution NuGet.config = NuGet.config EndProjectSection EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Aeon.Database", "Aeon.Database\Aeon.Database.csproj", "{D99F92A5-E825-4CDC-A7EB-849E860FB5B7}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Aeon.Database", "src\Aeon.Database\Aeon.Database.csproj", "{D99F92A5-E825-4CDC-A7EB-849E860FB5B7}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Aeon.Foraging", "Aeon.Foraging\Aeon.Foraging.csproj", "{2C814742-0F6D-40DC-B9B7-C54BDB95EE7F}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Aeon.Foraging", "src\Aeon.Foraging\Aeon.Foraging.csproj", "{2C814742-0F6D-40DC-B9B7-C54BDB95EE7F}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Aeon.Environment", "Aeon.Environment\Aeon.Environment.csproj", "{49FC1C61-791E-41CF-BB7C-C2AC26AFAFE3}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Aeon.Environment", "src\Aeon.Environment\Aeon.Environment.csproj", "{49FC1C61-791E-41CF-BB7C-C2AC26AFAFE3}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Aeon.Video", "src\Aeon.Video\Aeon.Video.csproj", "{1D11793E-85E9-473C-8EF6-F4BD4B249E30}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Aeon.Vision", "src\Aeon.Vision\Aeon.Vision.csproj", "{709D0302-5A4F-4F76-8596-41B74DF3B3E9}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Aeon.Vision.Sleap", "src\Aeon.Vision.Sleap\Aeon.Vision.Sleap.csproj", "{0D9D431D-EA23-4610-B262-313A48BFE34B}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -46,6 +52,18 @@ Global {49FC1C61-791E-41CF-BB7C-C2AC26AFAFE3}.Debug|Any CPU.Build.0 = Debug|Any CPU {49FC1C61-791E-41CF-BB7C-C2AC26AFAFE3}.Release|Any CPU.ActiveCfg = Release|Any CPU {49FC1C61-791E-41CF-BB7C-C2AC26AFAFE3}.Release|Any CPU.Build.0 = Release|Any CPU + {0D9D431D-EA23-4610-B262-313A48BFE34B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0D9D431D-EA23-4610-B262-313A48BFE34B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0D9D431D-EA23-4610-B262-313A48BFE34B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0D9D431D-EA23-4610-B262-313A48BFE34B}.Release|Any CPU.Build.0 = Release|Any CPU + {1D11793E-85E9-473C-8EF6-F4BD4B249E30}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1D11793E-85E9-473C-8EF6-F4BD4B249E30}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1D11793E-85E9-473C-8EF6-F4BD4B249E30}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1D11793E-85E9-473C-8EF6-F4BD4B249E30}.Release|Any CPU.Build.0 = Release|Any CPU + {709D0302-5A4F-4F76-8596-41B74DF3B3E9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {709D0302-5A4F-4F76-8596-41B74DF3B3E9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {709D0302-5A4F-4F76-8596-41B74DF3B3E9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {709D0302-5A4F-4F76-8596-41B74DF3B3E9}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/src/Directory.Build.props b/Directory.Build.props similarity index 87% rename from src/Directory.Build.props rename to Directory.Build.props index 09d06be..41ae192 100644 --- a/src/Directory.Build.props +++ b/Directory.Build.props @@ -5,13 +5,13 @@ Copyright © 2023-2024 University College London https://sainsburywellcomecentre.github.io/aeon_docs https://github.com/SainsburyWellcomeCentre/aeon_acquisition.git - true snupkg - ..\bin\$(Configuration) LICENSE + true icon.png true git + 0.7.0 9.0 strict diff --git a/src/NuGet.config b/NuGet.config similarity index 100% rename from src/NuGet.config rename to NuGet.config diff --git a/bonsai/Bonsai.config b/bonsai/Bonsai.config deleted file mode 100644 index 4caead7..0000000 --- a/bonsai/Bonsai.config +++ /dev/null @@ -1,123 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/bonsai/setup.cmd b/bonsai/setup.cmd deleted file mode 100644 index 3c53f3a..0000000 --- a/bonsai/setup.cmd +++ /dev/null @@ -1 +0,0 @@ -powershell -ExecutionPolicy Bypass -File .\setup.ps1 \ No newline at end of file diff --git a/bonsai/setup.ps1 b/bonsai/setup.ps1 deleted file mode 100644 index 235aafc..0000000 --- a/bonsai/setup.ps1 +++ /dev/null @@ -1,10 +0,0 @@ -if (!(Test-Path "./Bonsai.exe")) { - & dotnet build ../src/Aeon.sln --configuration Release - Invoke-WebRequest "https://github.com/bonsai-rx/bonsai/releases/download/2.7-rc1/Bonsai.zip" -OutFile "temp.zip" - Move-Item -Path "NuGet.config" "temp.config" - Expand-Archive "temp.zip" -DestinationPath "." -Force - Move-Item -Path "temp.config" "NuGet.config" -Force - Remove-Item -Path "temp.zip" - Remove-Item -Path "Bonsai32.exe" -} -& .\Bonsai.exe --no-editor \ No newline at end of file diff --git a/calibration/calibcamera.py b/calibration/calibcamera.py deleted file mode 100644 index 9adfa1c..0000000 --- a/calibration/calibcamera.py +++ /dev/null @@ -1,66 +0,0 @@ -import os -import cv2 -import glob -import numpy as np -import matplotlib.pyplot as plt -import argparse - -parser = argparse.ArgumentParser(description="Camera checkerboard calibration. Assumes a checkerboard with 8x12 inner corners.") -parser.add_argument('dname', type=str, help="The path to a folder with checkerboard images to use for camera calibration.") -args = parser.parse_args() - -patternsize = (8, 12) -pattern = np.zeros((1, patternsize[0] * patternsize[1], 3), np.float32) -pattern[0,:,:2] = np.mgrid[0:patternsize[0], 0:patternsize[1]].T.reshape(-1, 2) -criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001) - -objectPoints = [] -imagePoints = [] -fnames = glob.glob(args.dname + '/*.png') -for fname in fnames: - print("Processing {0}...".format(os.path.split(fname)[-1]), end=" ") - img = cv2.imread(fname) - gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) - - flags = cv2.CALIB_CB_ADAPTIVE_THRESH + cv2.CALIB_CB_FAST_CHECK + cv2.CALIB_CB_NORMALIZE_IMAGE - ret, corners = cv2.findChessboardCorners(gray, patternsize, flags) - print("Success" if ret else "Not found!") - - if ret: - corners = cv2.cornerSubPix(gray, corners, (11, 11), (-1, -1), criteria) - objectPoints.append(pattern) - imagePoints.append(corners) - - img = cv2.drawChessboardCorners(img, patternsize, corners, ret) - - plt.imshow(img) - plt.draw() - plt.waitforbuttonpress(timeout=0.1) - -print("Calibrating camera with {0} points from {1} images...".format( - np.prod(np.array(imagePoints).shape) // 2, - len(imagePoints))) -ret, intrinsics, distortion, rvecs, tvecs = cv2.calibrateCamera( - objectPoints, imagePoints, gray.shape[::-1], None, None) -print("Reprojection error: {0}".format(ret)) - -fname = "{0}.yml".format(os.path.split(args.dname)[-1]) -print("Writing calibration file {0}...".format(fname)) -flags = cv2.FILE_STORAGE_FORMAT_YAML + cv2.FILE_STORAGE_WRITE -f = cv2.FileStorage(args.dname + '/' + fname,flags) -f.write('image_width', img.shape[1]) -f.write('image_height', img.shape[0]) -f.write('camera_matrix', intrinsics) -f.write('distortion_coefficients', distortion) -f.write('reprojection_error', ret) -f.release() - -for i,fname in enumerate(fnames): - print("Undistorting {0}...".format(os.path.split(fname)[-1])) - img = cv2.imread(fname) - img = cv2.drawChessboardCorners(img, patternsize, imagePoints[i], True) - - uimg = cv2.undistort(img, intrinsics, distortion) - plt.imshow(uimg) - plt.draw() - plt.waitforbuttonpress(timeout=0.1) \ No newline at end of file diff --git a/calibration/metadata.py b/calibration/metadata.py deleted file mode 100644 index 3e2a545..0000000 --- a/calibration/metadata.py +++ /dev/null @@ -1,65 +0,0 @@ -from pathlib import Path -from lxml import etree -from git import Repo -import argparse -import json -import sys - -parser = argparse.ArgumentParser(description="Exports device and experiment metadata for the specified workflow file.") -parser.add_argument('workflow', type=str, help="The path to the workflow file used for data acquisition.") -parser.add_argument('--indent', type=int, help="The optional indent level for JSON pretty printing.") -parser.add_argument('--allow-dirty', action="store_true", help="Optionally allow exporting metadata for modified repositories.") -parser.add_argument('--output', type=str, help="The optional path to the exported JSON file.") -args = parser.parse_args() -dname = Path(__file__).parent - -repo = Repo(dname.parent) -if not args.allow_dirty and (repo.is_dirty() or len(repo.untracked_files) > 0): - parser.error("all modifications to the acquisition repository must be committed before exporting metadata") - -ns = { - 'x' : 'https://bonsai-rx.org/2018/workflow', - 'xsi' : 'http://www.w3.org/2001/XMLSchema-instance' -} - -def recursive_dict(element): - return etree.QName(element).localname, \ - dict(map(recursive_dict, element)) or element.text - -def list_metadata(elements, key, **kwargs): - metadata = [] - for x in elements: - elem_metadata = {} - elem_metadata = (recursive_dict(x)[1]) - elem_metadata.update(kwargs) - elem_metadata['Name'] = elem_metadata.pop(key, key) - metadata.append(elem_metadata) - return metadata - -root = etree.parse(args.workflow) -workflow = root.xpath('/x:WorkflowBuilder/x:Workflow/x:Nodes', namespaces=ns)[0] -hardware = workflow.xpath('./x:Expression[@xsi:type="GroupWorkflow" and ./x:Name[text()="Hardware"]]/x:Workflow/x:Nodes', namespaces=ns)[0] - -video_controllers = hardware.xpath('./x:Expression[@Path="Aeon.Acquisition:VideoController.bonsai"]', namespaces=ns) -video_sources = hardware.xpath('./x:Expression[@Path="Aeon.Acquisition:VideoSource.bonsai"]', namespaces=ns) -audio_sources = hardware.xpath('./x:Expression[@Path="Aeon.Acquisition:AudioSource.bonsai"]', namespaces=ns) -patches = hardware.xpath('./x:Expression[@Path="Aeon.Acquisition:PatchController.bonsai"]', namespaces=ns) -weight_scales = hardware.xpath('./x:Expression[@Path="Aeon.Acquisition:WeightScale.bonsai"]', namespaces=ns) -position_tracking = hardware.xpath('./x:Expression[@Path="Aeon.Acquisition:PositionTracking.bonsai"]', namespaces=ns) - -metadata = { - 'Workflow' : args.workflow, - 'Revision' : repo.head.commit.hexsha, - 'Devices' : list_metadata(video_controllers, 'VideoController', Type='VideoController') + - list_metadata(video_sources, 'FrameEvents', Type='VideoSource') + - list_metadata(audio_sources, 'AudioAmbient', Type='AudioSource') + - list_metadata(patches, 'PatchEvents', Type='Patch') + - list_metadata(weight_scales, 'WeightEvents', Type='WeightScale') + - list_metadata(position_tracking, 'TrackingEvents', Type='PositionTracking') -} - -if args.output: - with open(args.output, "w") as outfile: - json.dump(metadata, outfile, indent=args.indent) -else: - json.dump(metadata, sys.stdout, indent=args.indent) \ No newline at end of file diff --git a/calibration/targets/calib.io_checker_420x594_13x9_40.pdf b/calibration/targets/calib.io_checker_420x594_13x9_40.pdf deleted file mode 100644 index 256f653..0000000 Binary files a/calibration/targets/calib.io_checker_420x594_13x9_40.pdf and /dev/null differ diff --git a/calibration/targets/calib.io_checker_85.6x53.98_9x13_5.pdf b/calibration/targets/calib.io_checker_85.6x53.98_9x13_5.pdf deleted file mode 100644 index dcf9721..0000000 Binary files a/calibration/targets/calib.io_checker_85.6x53.98_9x13_5.pdf and /dev/null differ diff --git a/python/requirements.txt b/python/requirements.txt deleted file mode 100644 index 8e36a5f..0000000 --- a/python/requirements.txt +++ /dev/null @@ -1,4 +0,0 @@ -matplotlib~=3.4.3 -opencv-python~=4.5.3 -lxml>=4.9.1 -GitPython~=3.1.24 \ No newline at end of file diff --git a/python/setup.cmd b/python/setup.cmd deleted file mode 100644 index 3c53f3a..0000000 --- a/python/setup.cmd +++ /dev/null @@ -1 +0,0 @@ -powershell -ExecutionPolicy Bypass -File .\setup.ps1 \ No newline at end of file diff --git a/python/setup.ps1 b/python/setup.ps1 deleted file mode 100644 index 8d124fa..0000000 --- a/python/setup.ps1 +++ /dev/null @@ -1,9 +0,0 @@ -if (!(Test-Path "./winpython")) { - Invoke-WebRequest "https://github.com/winpython/winpython/releases/download/4.3.20210620/Winpython64-3.9.5.0dot.exe" -OutFile "temp.exe" - $process = Start-Process "temp.exe" "-y" -PassThru - $process.WaitForExit() - Rename-Item -Path "WPy64-3950" -NewName "winpython" - Remove-Item -Path "temp.exe" -} - -cmd.exe /c '.\winpython\scripts\env.bat && pip install -r requirements.txt' \ No newline at end of file diff --git a/src/Aeon.Acquisition/Aeon.Acquisition.csproj b/src/Aeon.Acquisition/Aeon.Acquisition.csproj index 354f117..cc043b1 100644 --- a/src/Aeon.Acquisition/Aeon.Acquisition.csproj +++ b/src/Aeon.Acquisition/Aeon.Acquisition.csproj @@ -5,8 +5,6 @@ A package providing common acquisition and control functionality for all Project Aeon experiments. Bonsai Rx Project Aeon Acquisition net472 - 0.6.0 - @@ -14,25 +12,17 @@ - + - - - + - - - - - - - + + - - - + + diff --git a/src/Aeon.Acquisition/ObservableExtensions.cs b/src/Aeon.Acquisition/ObservableExtensions.cs index c0a10ad..d52e9d4 100644 --- a/src/Aeon.Acquisition/ObservableExtensions.cs +++ b/src/Aeon.Acquisition/ObservableExtensions.cs @@ -7,48 +7,8 @@ namespace Aeon.Acquisition { - public static class ObservableExtensions + internal static class ObservableExtensions { - public static IObservable FillGaps(this IObservable source, Func gapSelector) - { - return FillGaps(source, value => value, gapSelector); - } - - public static IObservable FillGaps( - this IObservable source, - Func counterSelector, - Func gapSelector) - { - return Observable.Create(observer => - { - bool hasPrevious = false; - TCounter previousCounter = default; - var gapObserver = Observer.Create(value => - { - var counter = counterSelector(value); - if (hasPrevious) - { - var missing = gapSelector(previousCounter, counter); - if (missing < 0) - { - observer.OnError(new InvalidOperationException( - $"Negative gap sizes are not allowed.\n Previous counter: {previousCounter}\n Current counter: {counter}")); - } - - while (missing > 0) - { - observer.OnNext(default); - missing--; - } - } - observer.OnNext(value); - previousCounter = counter; - hasPrevious = true; - }); - return source.SubscribeSafe(gapObserver); - }); - } - public static IObservable MergeUnit(this IObservable source, IObservable other) { return source.Select(x => Unit.Default).Merge(other.Select(x => Unit.Default)); diff --git a/src/Aeon.Acquisition/Properties/launchSettings.json b/src/Aeon.Acquisition/Properties/launchSettings.json index b48bcfa..11dbb0a 100644 --- a/src/Aeon.Acquisition/Properties/launchSettings.json +++ b/src/Aeon.Acquisition/Properties/launchSettings.json @@ -2,7 +2,7 @@ "profiles": { "Bonsai": { "commandName": "Executable", - "executablePath": "$(registry:HKEY_CURRENT_USER\\Software\\Bonsai Foundation\\Bonsai@InstallDir)Bonsai.exe", + "executablePath": "$(SolutionDir).bonsai/Bonsai.exe", "commandLineArgs": "--lib:\"$(TargetDir).\"", "nativeDebugging": true } diff --git a/src/Aeon.Database/Aeon.Database.csproj b/src/Aeon.Database/Aeon.Database.csproj index 9fdcbc2..c3bcf5b 100644 --- a/src/Aeon.Database/Aeon.Database.csproj +++ b/src/Aeon.Database/Aeon.Database.csproj @@ -5,7 +5,6 @@ Provides querying and schema functionality for Project Aeon databases. Bonsai Rx Project Aeon Database net472 - 0.1.0 @@ -14,8 +13,8 @@ - - + + diff --git a/src/Aeon.Database/DataReaderExtensions.cs b/src/Aeon.Database/DataReaderExtensions.cs index f1c2c41..c369cdc 100644 --- a/src/Aeon.Database/DataReaderExtensions.cs +++ b/src/Aeon.Database/DataReaderExtensions.cs @@ -4,7 +4,7 @@ namespace Aeon.Database { - public static class DataReaderExtensions + internal static class DataReaderExtensions { public static IEnumerable GetRecords(this MySqlDataReader reader) { diff --git a/src/Aeon.Database/Properties/launchSettings.json b/src/Aeon.Database/Properties/launchSettings.json index b48bcfa..11dbb0a 100644 --- a/src/Aeon.Database/Properties/launchSettings.json +++ b/src/Aeon.Database/Properties/launchSettings.json @@ -2,7 +2,7 @@ "profiles": { "Bonsai": { "commandName": "Executable", - "executablePath": "$(registry:HKEY_CURRENT_USER\\Software\\Bonsai Foundation\\Bonsai@InstallDir)Bonsai.exe", + "executablePath": "$(SolutionDir).bonsai/Bonsai.exe", "commandLineArgs": "--lib:\"$(TargetDir).\"", "nativeDebugging": true } diff --git a/src/Aeon.Environment/Aeon.Environment.csproj b/src/Aeon.Environment/Aeon.Environment.csproj index 7f73a17..cbd6ec2 100644 --- a/src/Aeon.Environment/Aeon.Environment.csproj +++ b/src/Aeon.Environment/Aeon.Environment.csproj @@ -6,7 +6,6 @@ Provides reactive modules for controlling and monitoring Project Aeon environments. Bonsai Rx Project Aeon Environment net472 - 0.1.0 @@ -15,7 +14,9 @@ - + + + diff --git a/src/Aeon.Environment/Properties/launchSettings.json b/src/Aeon.Environment/Properties/launchSettings.json index b48bcfa..11dbb0a 100644 --- a/src/Aeon.Environment/Properties/launchSettings.json +++ b/src/Aeon.Environment/Properties/launchSettings.json @@ -2,7 +2,7 @@ "profiles": { "Bonsai": { "commandName": "Executable", - "executablePath": "$(registry:HKEY_CURRENT_USER\\Software\\Bonsai Foundation\\Bonsai@InstallDir)Bonsai.exe", + "executablePath": "$(SolutionDir).bonsai/Bonsai.exe", "commandLineArgs": "--lib:\"$(TargetDir).\"", "nativeDebugging": true } diff --git a/src/Aeon.Foraging/Aeon.Foraging.csproj b/src/Aeon.Foraging/Aeon.Foraging.csproj index 44e8401..3efd0c4 100644 --- a/src/Aeon.Foraging/Aeon.Foraging.csproj +++ b/src/Aeon.Foraging/Aeon.Foraging.csproj @@ -6,7 +6,6 @@ Provides acquisition and control modules for Project Aeon foraging experiments. Bonsai Rx Project Aeon Foraging net472 - 0.1.2 @@ -15,7 +14,7 @@ - + diff --git a/src/Aeon.Foraging/Properties/launchSettings.json b/src/Aeon.Foraging/Properties/launchSettings.json index b48bcfa..11dbb0a 100644 --- a/src/Aeon.Foraging/Properties/launchSettings.json +++ b/src/Aeon.Foraging/Properties/launchSettings.json @@ -2,7 +2,7 @@ "profiles": { "Bonsai": { "commandName": "Executable", - "executablePath": "$(registry:HKEY_CURRENT_USER\\Software\\Bonsai Foundation\\Bonsai@InstallDir)Bonsai.exe", + "executablePath": "$(SolutionDir).bonsai/Bonsai.exe", "commandLineArgs": "--lib:\"$(TargetDir).\"", "nativeDebugging": true } diff --git a/src/Aeon.Tests/Aeon.Tests.csproj b/src/Aeon.Tests/Aeon.Tests.csproj index fcd9983..1c7cd4f 100644 --- a/src/Aeon.Tests/Aeon.Tests.csproj +++ b/src/Aeon.Tests/Aeon.Tests.csproj @@ -11,10 +11,10 @@ - - - - + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive @@ -24,6 +24,9 @@ + + + diff --git a/src/Aeon.Tests/AssertWorkflow.cs b/src/Aeon.Tests/AssertWorkflow.cs index 4a80e0c..785169e 100644 --- a/src/Aeon.Tests/AssertWorkflow.cs +++ b/src/Aeon.Tests/AssertWorkflow.cs @@ -4,14 +4,14 @@ using System.IO; using Bonsai.Expressions; using Microsoft.VisualStudio.TestTools.UnitTesting; -using Aeon.Acquisition; +using Aeon.Video; using System; namespace Aeon.Tests { public static class AssertWorkflow { - public static void CanBuildEmbeddedResources(Assembly assembly) + public static void CanLoadEmbeddedResources(Assembly assembly) { foreach (var name in assembly.GetManifestResourceNames()) { diff --git a/src/Aeon.Tests/OperatorTests.cs b/src/Aeon.Tests/OperatorTests.cs index 3789e1b..aac16b2 100644 --- a/src/Aeon.Tests/OperatorTests.cs +++ b/src/Aeon.Tests/OperatorTests.cs @@ -1,6 +1,9 @@ using Aeon.Acquisition; using Aeon.Environment; using Aeon.Foraging; +using Aeon.Video; +using Aeon.Vision; +using Aeon.Vision.Sleap; using Microsoft.VisualStudio.TestTools.UnitTesting; namespace Aeon.Tests @@ -9,14 +12,25 @@ namespace Aeon.Tests public class OperatorTests { [TestMethod] - public void Build_Workflows() + public void Load_Workflows() { var acquisition = typeof(GroupByTime).Assembly; var environment = typeof(EnvironmentState).Assembly; var foraging = typeof(WheelDisplacement).Assembly; - AssertWorkflow.CanBuildEmbeddedResources(acquisition); - AssertWorkflow.CanBuildEmbeddedResources(environment); - AssertWorkflow.CanBuildEmbeddedResources(foraging); + var vision = typeof(DistanceFromPoint).Assembly; + var sleap = typeof(FormatPose).Assembly; + AssertWorkflow.CanLoadEmbeddedResources(acquisition); + AssertWorkflow.CanLoadEmbeddedResources(environment); + AssertWorkflow.CanLoadEmbeddedResources(foraging); + AssertWorkflow.CanLoadEmbeddedResources(vision); + AssertWorkflow.CanLoadEmbeddedResources(sleap); + } + + [TestMethod, TestCategory("DriverDependent")] + public void Load_DriverDependentWorkflows() + { + var video = typeof(VideoDataFrame).Assembly; + AssertWorkflow.CanLoadEmbeddedResources(video); } } } diff --git a/src/Aeon.Video/Aeon.Video.csproj b/src/Aeon.Video/Aeon.Video.csproj new file mode 100644 index 0000000..5dcb6cc --- /dev/null +++ b/src/Aeon.Video/Aeon.Video.csproj @@ -0,0 +1,29 @@ + + + + true + Project Aeon - Video + Provides reactive modules for video acquisition in Project Aeon experiments. + Bonsai Rx Project Aeon Video + net472 + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Aeon.Acquisition/CameraController.bonsai b/src/Aeon.Video/CameraController.bonsai similarity index 100% rename from src/Aeon.Acquisition/CameraController.bonsai rename to src/Aeon.Video/CameraController.bonsai diff --git a/src/Aeon.Acquisition/FileVideoSource.bonsai b/src/Aeon.Video/FileVideoSource.bonsai similarity index 96% rename from src/Aeon.Acquisition/FileVideoSource.bonsai rename to src/Aeon.Video/FileVideoSource.bonsai index db5b8c5..6ac140b 100644 --- a/src/Aeon.Acquisition/FileVideoSource.bonsai +++ b/src/Aeon.Video/FileVideoSource.bonsai @@ -1,7 +1,7 @@  diff --git a/src/Aeon.Acquisition/LogVideo.bonsai b/src/Aeon.Video/LogVideo.bonsai similarity index 100% rename from src/Aeon.Acquisition/LogVideo.bonsai rename to src/Aeon.Video/LogVideo.bonsai diff --git a/src/Aeon.Video/ObservableExtensions.cs b/src/Aeon.Video/ObservableExtensions.cs new file mode 100644 index 0000000..8cfd2b2 --- /dev/null +++ b/src/Aeon.Video/ObservableExtensions.cs @@ -0,0 +1,49 @@ +using System; +using System.Reactive; +using System.Reactive.Linq; + +namespace Aeon.Video +{ + internal static class ObservableExtensions + { + public static IObservable FillGaps(this IObservable source, Func gapSelector) + { + return FillGaps(source, value => value, gapSelector); + } + + public static IObservable FillGaps( + this IObservable source, + Func counterSelector, + Func gapSelector) + { + return Observable.Create(observer => + { + bool hasPrevious = false; + TCounter previousCounter = default; + var gapObserver = Observer.Create(value => + { + var counter = counterSelector(value); + if (hasPrevious) + { + var missing = gapSelector(previousCounter, counter); + if (missing < 0) + { + observer.OnError(new InvalidOperationException( + $"Negative gap sizes are not allowed.\n Previous counter: {previousCounter}\n Current counter: {counter}")); + } + + while (missing > 0) + { + observer.OnNext(default); + missing--; + } + } + observer.OnNext(value); + previousCounter = counter; + hasPrevious = true; + }); + return source.SubscribeSafe(gapObserver); + }); + } + } +} diff --git a/src/Aeon.Video/Properties/AssemblyInfo.cs b/src/Aeon.Video/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..b5f6d0d --- /dev/null +++ b/src/Aeon.Video/Properties/AssemblyInfo.cs @@ -0,0 +1,6 @@ +using Bonsai; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: XmlNamespacePrefix("clr-namespace:Aeon.Video", "aeon-video")] diff --git a/src/Aeon.Video/Properties/launchSettings.json b/src/Aeon.Video/Properties/launchSettings.json new file mode 100644 index 0000000..11dbb0a --- /dev/null +++ b/src/Aeon.Video/Properties/launchSettings.json @@ -0,0 +1,10 @@ +{ + "profiles": { + "Bonsai": { + "commandName": "Executable", + "executablePath": "$(SolutionDir).bonsai/Bonsai.exe", + "commandLineArgs": "--lib:\"$(TargetDir).\"", + "nativeDebugging": true + } + } +} \ No newline at end of file diff --git a/src/Aeon.Acquisition/PylonCapture.cs b/src/Aeon.Video/PylonCapture.cs similarity index 97% rename from src/Aeon.Acquisition/PylonCapture.cs rename to src/Aeon.Video/PylonCapture.cs index 8c6709e..83ec4f5 100644 --- a/src/Aeon.Acquisition/PylonCapture.cs +++ b/src/Aeon.Video/PylonCapture.cs @@ -6,7 +6,7 @@ using Bonsai.Harp; using Basler.Pylon; -namespace Aeon.Acquisition +namespace Aeon.Video { [Description("Configures and initializes a Pylon camera for triggered acquisition.")] public class PylonCapture : Bonsai.Pylon.PylonCapture diff --git a/src/Aeon.Acquisition/PylonVideoSource.bonsai b/src/Aeon.Video/PylonVideoSource.bonsai similarity index 95% rename from src/Aeon.Acquisition/PylonVideoSource.bonsai rename to src/Aeon.Video/PylonVideoSource.bonsai index 185d78b..2b4e6db 100644 --- a/src/Aeon.Acquisition/PylonVideoSource.bonsai +++ b/src/Aeon.Video/PylonVideoSource.bonsai @@ -1,7 +1,7 @@  diff --git a/src/Aeon.Acquisition/SpinnakerCapture.cs b/src/Aeon.Video/SpinnakerCapture.cs similarity index 99% rename from src/Aeon.Acquisition/SpinnakerCapture.cs rename to src/Aeon.Video/SpinnakerCapture.cs index bda960c..31bba45 100644 --- a/src/Aeon.Acquisition/SpinnakerCapture.cs +++ b/src/Aeon.Video/SpinnakerCapture.cs @@ -6,7 +6,7 @@ using SpinnakerNET; using Bonsai.Harp; -namespace Aeon.Acquisition +namespace Aeon.Video { [Description("Configures and initializes a Spinnaker camera for triggered acquisition.")] public class SpinnakerCapture : Bonsai.Spinnaker.SpinnakerCapture diff --git a/src/Aeon.Acquisition/SpinnakerVideoSource.bonsai b/src/Aeon.Video/SpinnakerVideoSource.bonsai similarity index 97% rename from src/Aeon.Acquisition/SpinnakerVideoSource.bonsai rename to src/Aeon.Video/SpinnakerVideoSource.bonsai index 3b98612..351eb1d 100644 --- a/src/Aeon.Acquisition/SpinnakerVideoSource.bonsai +++ b/src/Aeon.Video/SpinnakerVideoSource.bonsai @@ -2,7 +2,7 @@ > diff --git a/src/Aeon.Vision.Sleap/Aeon.Vision.Sleap.csproj b/src/Aeon.Vision.Sleap/Aeon.Vision.Sleap.csproj new file mode 100644 index 0000000..3eaf9f8 --- /dev/null +++ b/src/Aeon.Vision.Sleap/Aeon.Vision.Sleap.csproj @@ -0,0 +1,24 @@ + + + + true + Project Aeon - SLEAP + Provides reactive modules for SLEAP based pose estimation used for Project Aeon experiments. + Bonsai Rx Project Aeon Vision Sleap + net472 + + + + + + + + + + + + + + + + diff --git a/src/Aeon.Acquisition/CreatePoseTrackingMetadata.cs b/src/Aeon.Vision.Sleap/CreatePoseTrackingMetadata.cs similarity index 99% rename from src/Aeon.Acquisition/CreatePoseTrackingMetadata.cs rename to src/Aeon.Vision.Sleap/CreatePoseTrackingMetadata.cs index 1625889..72171d0 100644 --- a/src/Aeon.Acquisition/CreatePoseTrackingMetadata.cs +++ b/src/Aeon.Vision.Sleap/CreatePoseTrackingMetadata.cs @@ -5,7 +5,7 @@ using System.Reactive.Linq; using Bonsai; -namespace Aeon.Acquisition +namespace Aeon.Vision.Sleap { [Description("Initializes a pose tracking metadata object from the specified model path.")] public class CreatePoseTrackingMetadata : Source diff --git a/src/Aeon.Acquisition/FormatPose.cs b/src/Aeon.Vision.Sleap/FormatPose.cs similarity index 99% rename from src/Aeon.Acquisition/FormatPose.cs rename to src/Aeon.Vision.Sleap/FormatPose.cs index f1e1403..a2dd3d0 100644 --- a/src/Aeon.Acquisition/FormatPose.cs +++ b/src/Aeon.Vision.Sleap/FormatPose.cs @@ -6,7 +6,7 @@ using Bonsai.Sleap; using Bonsai.Harp; -namespace Aeon.Acquisition +namespace Aeon.Vision.Sleap { [Combinator] [Description("Converts a timestamped pose collection into a sequence of Harp messages.")] diff --git a/src/Aeon.Acquisition/LogPoseTracking.bonsai b/src/Aeon.Vision.Sleap/LogPoseTracking.bonsai similarity index 97% rename from src/Aeon.Acquisition/LogPoseTracking.bonsai rename to src/Aeon.Vision.Sleap/LogPoseTracking.bonsai index 8f205aa..2bc3a52 100644 --- a/src/Aeon.Acquisition/LogPoseTracking.bonsai +++ b/src/Aeon.Vision.Sleap/LogPoseTracking.bonsai @@ -1,7 +1,7 @@  diff --git a/src/Aeon.Acquisition/PoseTracking.bonsai b/src/Aeon.Vision.Sleap/PoseTracking.bonsai similarity index 97% rename from src/Aeon.Acquisition/PoseTracking.bonsai rename to src/Aeon.Vision.Sleap/PoseTracking.bonsai index 849f6e5..52c1a03 100644 --- a/src/Aeon.Acquisition/PoseTracking.bonsai +++ b/src/Aeon.Vision.Sleap/PoseTracking.bonsai @@ -1,7 +1,7 @@  + + + true + Project Aeon - Tracking + Provides reactive modules for computer vision used for Project Aeon experiments. + Bonsai Rx Project Aeon Vision + net472 + + + + + + + + + + + + + + + + diff --git a/src/Aeon.Acquisition/DistanceFromPoint.cs b/src/Aeon.Vision/DistanceFromPoint.cs similarity index 98% rename from src/Aeon.Acquisition/DistanceFromPoint.cs rename to src/Aeon.Vision/DistanceFromPoint.cs index 127f292..1aa7ed1 100644 --- a/src/Aeon.Acquisition/DistanceFromPoint.cs +++ b/src/Aeon.Vision/DistanceFromPoint.cs @@ -7,7 +7,7 @@ using System.Linq; using System.Reactive.Linq; -namespace Aeon.Acquisition +namespace Aeon.Vision { [Combinator] [Description("Computes the distance from every component in the sequence to a point.")] diff --git a/src/Aeon.Acquisition/FormatBinaryRegions.cs b/src/Aeon.Vision/FormatBinaryRegions.cs similarity index 98% rename from src/Aeon.Acquisition/FormatBinaryRegions.cs rename to src/Aeon.Vision/FormatBinaryRegions.cs index e17c5c2..3608e3a 100644 --- a/src/Aeon.Acquisition/FormatBinaryRegions.cs +++ b/src/Aeon.Vision/FormatBinaryRegions.cs @@ -6,7 +6,7 @@ using Bonsai.Vision; using Bonsai.Harp; -namespace Aeon.Acquisition +namespace Aeon.Vision { [Combinator] [Description("Converts timestamped binary regions into a sequence of Harp messages.")] diff --git a/src/Aeon.Acquisition/PositionTracking.bonsai b/src/Aeon.Vision/PositionTracking.bonsai similarity index 98% rename from src/Aeon.Acquisition/PositionTracking.bonsai rename to src/Aeon.Vision/PositionTracking.bonsai index 514dee1..f6b158d 100644 --- a/src/Aeon.Acquisition/PositionTracking.bonsai +++ b/src/Aeon.Vision/PositionTracking.bonsai @@ -3,7 +3,7 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:cv="clr-namespace:Bonsai.Vision;assembly=Bonsai.Vision" xmlns:rx="clr-namespace:Bonsai.Reactive;assembly=Bonsai.Core" - xmlns:aeon="clr-namespace:Aeon.Acquisition;assembly=Aeon.Acquisition" + xmlns:aeon="clr-namespace:Aeon.Vision;assembly=Aeon.Vision" xmlns:harp="clr-namespace:Bonsai.Harp;assembly=Bonsai.Harp" xmlns="https://bonsai-rx.org/2018/workflow"> Extracts information on the largest binary blob in the input image. diff --git a/src/Aeon.Vision/Properties/AssemblyInfo.cs b/src/Aeon.Vision/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..28f1234 --- /dev/null +++ b/src/Aeon.Vision/Properties/AssemblyInfo.cs @@ -0,0 +1,6 @@ +using Bonsai; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: XmlNamespacePrefix("clr-namespace:Aeon.Vision", "aeon-vision")] diff --git a/src/Aeon.Vision/Properties/launchSettings.json b/src/Aeon.Vision/Properties/launchSettings.json new file mode 100644 index 0000000..11dbb0a --- /dev/null +++ b/src/Aeon.Vision/Properties/launchSettings.json @@ -0,0 +1,10 @@ +{ + "profiles": { + "Bonsai": { + "commandName": "Executable", + "executablePath": "$(SolutionDir).bonsai/Bonsai.exe", + "commandLineArgs": "--lib:\"$(TargetDir).\"", + "nativeDebugging": true + } + } +} \ No newline at end of file diff --git a/src/Aeon.Acquisition/RegionContainsPoint.cs b/src/Aeon.Vision/RegionContainsPoint.cs similarity index 98% rename from src/Aeon.Acquisition/RegionContainsPoint.cs rename to src/Aeon.Vision/RegionContainsPoint.cs index ed4b393..4ed4a95 100644 --- a/src/Aeon.Acquisition/RegionContainsPoint.cs +++ b/src/Aeon.Vision/RegionContainsPoint.cs @@ -7,7 +7,7 @@ using System.Linq; using System.Reactive.Linq; -namespace Aeon.Acquisition +namespace Aeon.Vision { [Combinator] [Description("Generates boolean values indicating whether each point in the sequence is inside a region of interest.")] diff --git a/src/Aeon.Acquisition/RegionTracking.bonsai b/src/Aeon.Vision/RegionTracking.bonsai similarity index 96% rename from src/Aeon.Acquisition/RegionTracking.bonsai rename to src/Aeon.Vision/RegionTracking.bonsai index 9520a8b..e882bd6 100644 --- a/src/Aeon.Acquisition/RegionTracking.bonsai +++ b/src/Aeon.Vision/RegionTracking.bonsai @@ -1,7 +1,7 @@  diff --git a/src/Aeon.Acquisition/TakeLargestRegions.cs b/src/Aeon.Vision/TakeLargestRegions.cs similarity index 96% rename from src/Aeon.Acquisition/TakeLargestRegions.cs rename to src/Aeon.Vision/TakeLargestRegions.cs index a52f2ef..85d6d2f 100644 --- a/src/Aeon.Acquisition/TakeLargestRegions.cs +++ b/src/Aeon.Vision/TakeLargestRegions.cs @@ -1,4 +1,4 @@ -using Bonsai; +using Bonsai; using System; using System.ComponentModel; using System.Linq; @@ -6,7 +6,7 @@ using Bonsai.Vision; using OpenCV.Net; -namespace Aeon.Acquisition +namespace Aeon.Vision { [Combinator] [Description("Takes the N-largest binary regions.")] @@ -33,4 +33,4 @@ public IObservable Process(IObservable - - - - - COM3 - 50 - 125 - - - 21053810 - 4 - 1 - GlobalTrigger - FrameTop - GlobalTriggerFrequency - - - Value.Image - - - TopView - - - - Source1 - - - - - - - - - - - 92 - 255 - Binary - - - - - External - ChainApproxNone - - 0 - 0 - - 400000 - - - - - - 1 - -1 - - - - - - - - 159 - 471 - - - 219 - 480 - - - 216 - 516 - - - 240 - 518 - - - 238 - 540 - - - 215 - 541 - - - 214 - 574 - - - 148 - 574 - - - - Binary - - 0 - 0 - 0 - 0 - - - - - - - - - - None - false - - - - - - - - mask.png - None - - - - - PT1S - PT0S - - - - StartCameras - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/workflows/CalibrateArenaMask.bonsai.layout b/workflows/CalibrateArenaMask.bonsai.layout deleted file mode 100644 index b5c0fd6..0000000 --- a/workflows/CalibrateArenaMask.bonsai.layout +++ /dev/null @@ -1,208 +0,0 @@ - - - - false - - 0 - 0 - - - 0 - 0 - - Normal - - - false - - 130 - 130 - - - 336 - 65 - - Normal - Bonsai.Design.ObjectTextVisualizer - - - - - - true - - -15 - 712 - - - 1203 - 746 - - Normal - Bonsai.Vision.Design.IplImageVisualizer - - - - - 5 - - - - false - - 0 - 0 - - - 0 - 0 - - Normal - - - true - - 270 - 535 - - - 778 - 648 - - Normal - Bonsai.Vision.Design.IplImageVisualizer - - - - - - true - - 1405 - 290 - - - 336 - 279 - - Normal - Bonsai.Vision.Design.ContoursVisualizer - - - - - - false - - 0 - 0 - - - 0 - 0 - - Normal - - - true - - 1125 - 691 - - - 336 - 279 - - Normal - Bonsai.Vision.Design.IplImageVisualizer - - - - - - false - - 0 - 0 - - - 0 - 0 - - Normal - - - false - - 0 - 0 - - - 0 - 0 - - Normal - - - false - - 0 - 0 - - - 0 - 0 - - Normal - - - false - - 0 - 0 - - - 0 - 0 - - Normal - - - false - - 0 - 0 - - - 0 - 0 - - Normal - - - false - - 0 - 0 - - - 0 - 0 - - Normal - - - false - - 0 - 0 - - - 0 - 0 - - Normal - - \ No newline at end of file diff --git a/workflows/TestSynchronizer.bonsai b/workflows/TestSynchronizer.bonsai deleted file mode 100644 index 24cb123..0000000 --- a/workflows/TestSynchronizer.bonsai +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - - PT1S - PT3S - - - - SynchronizeTimestamp - - - - Active - true - On - On - Disable - false - COM6 - - - - - - - - - \ No newline at end of file diff --git a/workflows/TestSynchronizer.bonsai.layout b/workflows/TestSynchronizer.bonsai.layout deleted file mode 100644 index d7fa003..0000000 --- a/workflows/TestSynchronizer.bonsai.layout +++ /dev/null @@ -1,42 +0,0 @@ - - - - true - - 0 - 0 - - - 0 - 0 - - Normal - Bonsai.Design.ObjectTextVisualizer - - - false - - 0 - 0 - - - 0 - 0 - - Normal - - - false - - 0 - 0 - - - 0 - 0 - - Normal - - \ No newline at end of file