diff --git a/articles/hardware/hs64/ts4231.md b/articles/hardware/hs64/ts4231.md index 9ec8cf9..7b769d6 100644 --- a/articles/hardware/hs64/ts4231.md +++ b/articles/hardware/hs64/ts4231.md @@ -11,21 +11,33 @@ tracking capabilities. ::: The operator generates a sequence of -[TS4231V1PositionDataFrames](xref:OpenEphys.Onix1.TS4231V1PositionDataFrame). A `TS4231V1PositionDataFrame` is emitted -when a receiver on the Headstage 64 captures a sequence of 12 optical signals from a pair of lighthouses which occurs at -30 Hz. Therefore, with no occlusions, the maximum achievable sample rate is 30 Hz per receiver. There are three -receivers on the Headstage 64, so `TS4231V1PositionData` can emit up to 3 `TS4231V1PositionDataFrames` in a single 30 Hz -sampling cycle. Of course, if occlusions cause receivers to miss optical signals, this rate will be reduced. +[TS4231V1PositionDataFrames](xref:OpenEphys.Onix1.TS4231V1PositionDataFrame). A +`TS4231V1PositionDataFrame` is emitted when a receiver on the Headstage 64 captures a sequence of 12 +optical signals from a pair of lighthouses which occurs at 30 Hz. Therefore, with no occlusions, the +maximum achievable sample rate is 30 Hz per receiver. There are three receivers on the Headstage 64, +so `TS4231V1PositionData` can emit up to 3 `TS4231V1PositionDataFrames` in a single 30 Hz sampling +cycle. Of course, if occlusions cause receivers to miss optical signals, this rate will be reduced. The `TS4231V1PositionData`'s `DeviceName` property is set to "Headstage64/TS4231V1". This links the `TS4231V1PositionData` operator to the corresponding configuration operator. -The [CsvWriter](xref:Bonsai.IO.CsvWriter) operator writes the `Clock`, and `Position` -members from the `TS4231V1PositionDataFrame` to a file with the following name format: `ts4231v1__.csv`. -Because `CsvWriter` is a _sink_ operator, its output sequence is equivalent to its input sequence. In other words, its -output is equivalent to `TS4231V1PositionData`'s output. Therefore, it's possible to use -[MemberSelector](xref:Bonsai.Expressions.MemberSelectorBuilder) operators on the -`CsvWriter` to select members from `TS4231V1PositionDataFrame`. This is most easily performed by clicking the relevant -members that appear by hovering over the "Output" option that appears in the context menu that appears after -right-clicking the `CsvWriter` node. The member is selected in -the workflow to help visualize the position data by double-clicking the node when the workflow is running \ No newline at end of file +The [CsvWriter](xref:Bonsai.IO.CsvWriter) operator writes the `Clock` and `Position` members from +the `TS4231V1PositionDataFrame` output by `TS4231V1PositionData` to a file with the following name +format: `uncalibrated-ts4231v1__.csv`. Because `CsvWriter` is a _sink_ operator, its +output sequence is equivalent to its input sequence. In other words, its output is equivalent to +`TS4231V1PositionData`'s output. Therefore, it's possible to connect it directly to + which takes `TS4231V1PositionDataFrame` as its +input. To learn how to use this operator to transform coordinates in the TS4231 device reference +frame to a reference frame that is more intuitive or relevant to teh experiment, checkout out the + tutorial page. + +`TS4231V1SpatialTransform` connects directly to another `CsvWriter` -- this one writes `Clock` and +`Position` members from the `TS4231V1PositionDataFrame` output by `TS4231V1PositionData` to a file +with the following name format: `calibrated-ts4231v1__.csv`. The +[MemberSelector](xref:Bonsai.Expressions.MemberSelectorBuilder) operator on the `CsvWriter` to +selects a members from `TS4231V1PositionDataFrame`. The easiest way to place a `MemberSelector` is +is to click the relevant members that appear by hovering over the "Output" +option that appears in the context menu that appears after right-clicking the `CsvWriter` node. The + member is selected in the workflow to help +visualize the position data by double-clicking the node when the workflow is running. For more +details on visualizing data, checkout the page. \ No newline at end of file diff --git a/articles/tutorials/calibrate-ts4231.md b/articles/tutorials/calibrate-ts4231.md new file mode 100644 index 0000000..f6629b2 --- /dev/null +++ b/articles/tutorials/calibrate-ts4231.md @@ -0,0 +1,143 @@ +--- +uid: calibrate-ts4231 +title: Calibrate Positional Tracking Data +--- + +This tutorial shows how to transform XYZ position coordinates measured by a TS4231 device which are +originally in the device's reference frame to coordinates that are in a reference frame that is more +intuitive or relevant to the experiment. This is performed by determining the position coordinates +of four points in both the TS4231 device's reference frame and the user-defined reference frame to +calculate a spatial transform matrix which transforms all coordinates measured by the TS4231 device to the +user-defined coordinate system. + +^^^ +![crop of figure 3 from "ONIX: a unified open-source platform..."](../../images/tutorials/calibrate-ts4231/ts4231-figure-demo.webp) +^^^ From figure 3 of [ONIX: a unified open-source platform for multimodal neural recording and perturbation during naturalistic behavior](https://www.nature.com/articles/s41592-024-02521-1), the TS4231 device was used to track a mouse's 3D position over the course of a 7.3-h-long recording. + +## Setup + +1. First, confirm the Lighthouse transmitters are properly mounted according to the [Lighthouse + Setup Guide](https://open-ephys.github.io/onix-docs/Hardware%20Guide/Lighthouses/setup.html) in + the ONIX Hardware docs. +1. Follow the [Getting Started](xref:getting-started) guide to set up and familiarize yourself with + Bonsai. In particular, [download the necessary Bonsai + packages](xref:install-configure-bonsai#package-installation) or [check for + updates](xref:install-configure-bonsai#update-packages) if they're already installed. +1. Copy the following workflow into the Bonsai workflow editor by hovering over the + workflow image and clicking on the clipboard icon that appears. + + ::: workflow + ![SVG of copyable TS4231 calibration workflow](../../workflows/tutorials/calibrate-ts4231/calibrate-ts4231.bonsai) + ::: + + Open Bonsai and paste this workflow by clicking the Bonsai workflow editor pane and pressing + Ctrl+V. + + Visit the and pages to develop a foundation on how to + use Bonsai to acquire data from an ONIX headstage that has a TS4231 device. The primary + difference between this workflow and the example Headstage 64 workflow is that this one has + a transform operator for converting coordinates in the TS4231V1 reference frame to a user defined + reference frame. +1. Before beginning the calibration process, confirm that the lighthouse configuration can measure + the position of your TS4231 device across the entire desired range. To do this, [start the + workflow](xref:workflow-editor#starting-the-workflow) and confirm that the + operator continually produces data as you slowly + move the headstage across the entire range of your arena while inspecting the + TS4231V1PositionData Position [visualizer](xref:visualize-data). If at some point the + TS4231V1PositionData operator stops producing data during this process (e.g. the Position + visualizer stops updating), the TS4231 receivers are either obstructed from or no longer within + range of the Lighthouse base station transmitters. Remedying this might require modifying the + lighthouse configuration or reducing the size of your arena. + +## TS4231 Spatial Data Calibration + +1. Open the TS4231V1 Position Calibration GUI. + + - Start the workflow. + - Open the Position visualizer. + - Click TS4231V1SpatialTransform node to show its properties in the properties panel. + - Click the ... next to the "SpatialTransform" property. + + ![Screenshot of blank TS4231V1 Calibration GUI](../../images/tutorials/calibrate-ts4231/calibration-gui.png) + +1. Mark four points in your behavioral arena. The position coordinates of these four points will be + measured both in the TS4231 reference frame by the TS4231 device itself and in the user-defined + reference frame (if they are not already known, for example, using some features in the behavioral + arena with known dimensions). Here is a simple way to choose the four points: + + 1. The user-defined origin + 2. A point in the behavioral arena along the user-defined X-axis + 3. A point in the behavioral arena along the user-defined Y-axis + 4. A point in the behavioral arena along the user-defined Z-axis + + > [!TIP] + > Choosing the furthest extent along the X, Y, & Z axes minimizes the propagation of measurement + > error into the spatial transformation matrix. Balance this consideration with ease of knowing + > or measuring those coordinates. + + Here is a real-world example of four sets of coordinates on our workbench that we use to + demonstrate the calibration process: + + ![Photo of four calibration points](../../images/tutorials/calibrate-ts4231/calibration-points.webp){width=75%} + + The light red space is an arbitrarily-defined working area for this demo. + Units are in cm. + +1. For each of the four points defined in the previous step: + + - Choose a row in the TS4231V1 Calibration GUI to correspond to that point. + - Place your TS4231 device at that point and click the Measure button in the + corresponding row. The GUI will start taking measurements from the TS4231 device as long as + the TS4231 device is within range of and unobstructed from the lighthouse transmitter. If + the TS4231 measurement completes successfully, the corresponding entry in form is + automatically populated. Otherwise, that entry stays empty. In either case, you will be + informed in the "Status Messages" text box. If the TS4231 measurement fails, you may have to + reorient your Headstage64 or go back to the step in the previous section that describes how + to make sure the lighthouse configuration covers the entire area that your TS4231 device + will occupy. + - Populate the X, Y, and Z entries of the user-defined coordinates column in the corresponding + row. + + > [!TIP] + > Be as precise and accurate as possible with both the placement of the + > TS4231 device and the manual measurements. Consider making a fixture to + > fix the orientation of the TS4231 device and help set it in positions that + > are more easily measured. + + Once all fields in the Calibration GUI are populated with valid entries, the spatial transform + matrix is automatically calculated. When the spatial transform matrix is calculated, this will + be indicated in the GUI's bottom status strip and the spatial transform matrix text box such as + in the following screenshot: + + ![Screenshot of TS4231V1 Calibration GUI with calculated matrix](../../images/tutorials/calibrate-ts4231/calibration-gui_matrix-calculated.png) + +1. After the spatial transform is calculated, click OK to proceed. This updates the spatial transform + matrix used by the TS4231V1SpatialTransform operator. This recalibrated spatial transform matrix + should be immediately apparent in the TS4231V1SpatialTransform position data visualizer. + + If you are presented with the following confirmation, return to the TS4231 Calibration GUI main + form to fix the entries that were indicated invalid in the confirmation dialog. + + ![Screenshot of TS4231V1 Calibration GUI confirmation dialog](../../images/tutorials/calibrate-ts4231/calibration-gui_confirmation-dialog.png) + +> [!IMPORTANT] +> After calibrating the TS4231V1 spatial transform matrix, it is important to not change the +> TS4231PositionData operator's P/Q property values or move the lighthouse base stations or else +> the calibrated spatial transform matrix will no longer be accurate. + +## Verify TS4231 Calibration + +After following one of the two methods in the previous section, [visualize](xref:visualize-data) the +calibrated data and confirm that the transformed data matches your expectations. Inspecting the +Position visualizer in Bonsai while moving the TS4231 device is a first-order test. To be more +robust, choose a bunch of points (none of which should be the four calibration points) and check +that their calibrated coordinates are what you expect. + +Below is an animation of the 3D trajectory reconstructed in Python synced with video data for +demonstration purposes. + + + + diff --git a/articles/tutorials/index.md b/articles/tutorials/index.md index e8376f7..fa32b31 100644 --- a/articles/tutorials/index.md +++ b/articles/tutorials/index.md @@ -4,7 +4,14 @@ title: Tutorials --- This section contains tutorials that demonstrate how to make the most of -the Bonsai library by combining ONIX with third party software tools +th OpenEphys.Onix1 Bonsai package by combining ONIX with third party software tools. - \ No newline at end of file +Tutorials include: + +- [Process & Listen to Ephys Data](xref:ephys-process-listen): serves as a primer for processing + data in Bonsai. +- [Visualize Data in the Open Ephys GUI](xref:ephys-socket): teaches how to stream ephys data from + Bonsai to the Open Ephys GUI through an intermediary TCP connection for advanced visualizations. +- [Calibrate TS4231 Measurements](xref:calibrate-ts4231): demonstrates how to convert TS4231 + position coordinates from the TS4231 device reference frame to a reference frame that is more + intuitive or relevant to the experimental system using the TS4231V1 Position Calibration GUI. \ No newline at end of file diff --git a/articles/tutorials/toc.yml b/articles/tutorials/toc.yml index f91f9f1..11f1b28 100644 --- a/articles/tutorials/toc.yml +++ b/articles/tutorials/toc.yml @@ -1,4 +1,6 @@ - href: index.md + expanded: true items: - href: ephys-processing-listening.md - href: ephys-socket.md + - href: calibrate-ts4231.md diff --git a/images/tutorials/calibrate-ts4231/calibration-gui.png b/images/tutorials/calibrate-ts4231/calibration-gui.png new file mode 100644 index 0000000..7bd2e27 Binary files /dev/null and b/images/tutorials/calibrate-ts4231/calibration-gui.png differ diff --git a/images/tutorials/calibrate-ts4231/calibration-gui_confirmation-dialog.png b/images/tutorials/calibrate-ts4231/calibration-gui_confirmation-dialog.png new file mode 100644 index 0000000..f287987 Binary files /dev/null and b/images/tutorials/calibrate-ts4231/calibration-gui_confirmation-dialog.png differ diff --git a/images/tutorials/calibrate-ts4231/calibration-gui_matrix-calculated.png b/images/tutorials/calibrate-ts4231/calibration-gui_matrix-calculated.png new file mode 100644 index 0000000..cb2a922 Binary files /dev/null and b/images/tutorials/calibrate-ts4231/calibration-gui_matrix-calculated.png differ diff --git a/images/tutorials/calibrate-ts4231/calibration-points.webp b/images/tutorials/calibrate-ts4231/calibration-points.webp new file mode 100644 index 0000000..508dc83 Binary files /dev/null and b/images/tutorials/calibrate-ts4231/calibration-points.webp differ diff --git a/images/tutorials/calibrate-ts4231/ts4231-calibration-demo.mp4 b/images/tutorials/calibrate-ts4231/ts4231-calibration-demo.mp4 new file mode 100644 index 0000000..b929f01 Binary files /dev/null and b/images/tutorials/calibrate-ts4231/ts4231-calibration-demo.mp4 differ diff --git a/images/tutorials/calibrate-ts4231/ts4231-figure-demo.webp b/images/tutorials/calibrate-ts4231/ts4231-figure-demo.webp new file mode 100644 index 0000000..3f159ae Binary files /dev/null and b/images/tutorials/calibrate-ts4231/ts4231-figure-demo.webp differ diff --git a/img-src/tutorials/calibrate-ts4231/calibration-points.xcf b/img-src/tutorials/calibrate-ts4231/calibration-points.xcf new file mode 100644 index 0000000..a9a2dee Binary files /dev/null and b/img-src/tutorials/calibrate-ts4231/calibration-points.xcf differ diff --git a/src/bonsai-onix1 b/src/bonsai-onix1 index b9bdc3c..096f9ba 160000 --- a/src/bonsai-onix1 +++ b/src/bonsai-onix1 @@ -1 +1 @@ -Subproject commit b9bdc3c0bb340843ff4288b6145308176307d81e +Subproject commit 096f9ba907f693afd0d5064361c78d87905eb1ff diff --git a/workflows/hardware/hs64/hs64.bonsai b/workflows/hardware/hs64/hs64.bonsai index 10d0b18..9e81bbd 100644 --- a/workflows/hardware/hs64/hs64.bonsai +++ b/workflows/hardware/hs64/hs64.bonsai @@ -203,7 +203,67 @@ - ts4231_.csv + uncalibrated_ts4231_.csv + false + false + FileCount + false + Clock,Position + + + + + + NaN + NaN + NaN + 1 + NaN + NaN + NaN + 1 + NaN + NaN + NaN + 1 + NaN + NaN + NaN + 1 + + NaN + NaN + NaN + + + + NaN + NaN + NaN + 1 + NaN + NaN + NaN + 1 + NaN + NaN + NaN + 1 + NaN + NaN + NaN + 1 + + NaN + NaN + NaN + + + + + + + calibrated_ts4231_.csv false false FileCount @@ -318,17 +378,19 @@ + - + - - + + - + + \ No newline at end of file diff --git a/workflows/hardware/hs64/ts4231.bonsai b/workflows/hardware/hs64/ts4231.bonsai index 16c1642..9144898 100644 --- a/workflows/hardware/hs64/ts4231.bonsai +++ b/workflows/hardware/hs64/ts4231.bonsai @@ -1,5 +1,5 @@  - + uncalibrated_ts4231_.csv false false - None + FileCount + false + Clock,Position + + + + + + NaN + NaN + NaN + 1 + NaN + NaN + NaN + 1 + NaN + NaN + NaN + 1 + NaN + NaN + NaN + 1 + + NaN + NaN + NaN + + + + NaN + NaN + NaN + 1 + NaN + NaN + NaN + 1 + NaN + NaN + NaN + 1 + NaN + NaN + NaN + 1 + + NaN + NaN + NaN + + + + + + + calibrated_ts4231_.csv + false + false + FileCount false Clock,Position @@ -35,6 +96,8 @@ + + \ No newline at end of file diff --git a/workflows/operators/TS4231V1SpatialTransform.bonsai b/workflows/operators/TS4231V1SpatialTransform.bonsai new file mode 100644 index 0000000..2ea5397 --- /dev/null +++ b/workflows/operators/TS4231V1SpatialTransform.bonsai @@ -0,0 +1,87 @@ + + + + + + + + 0 + 0 + 0 + + + 1 + 0 + 0 + + + + + + + + NaN + NaN + NaN + 1 + NaN + NaN + NaN + 1 + NaN + NaN + NaN + 1 + NaN + NaN + NaN + 1 + + NaN + NaN + NaN + + + + NaN + NaN + NaN + 1 + NaN + NaN + NaN + 1 + NaN + NaN + NaN + 1 + NaN + NaN + NaN + 1 + + NaN + NaN + NaN + + + + + + + SensorIndex + + + Position + + + + + + + + + \ No newline at end of file diff --git a/workflows/tutorials/calibrate-ts4231/calibrate-ts4231.bonsai b/workflows/tutorials/calibrate-ts4231/calibrate-ts4231.bonsai new file mode 100644 index 0000000..520fdd0 --- /dev/null +++ b/workflows/tutorials/calibrate-ts4231/calibrate-ts4231.bonsai @@ -0,0 +1,204 @@ + + + + + + + riffa + 0 + + + + + BreakoutBoard + + BreakoutBoard/Heartbeat + 0 + 100 + + + BreakoutBoard/AnalogIO + 6 + false + TenVolts + TenVolts + TenVolts + TenVolts + TenVolts + TenVolts + TenVolts + TenVolts + TenVolts + TenVolts + TenVolts + TenVolts + Input + Input + Input + Input + Input + Input + Input + Input + Input + Input + Input + Input + + + BreakoutBoard/DigitalIO + 7 + false + 0 + + + + BreakoutBoard/OutputClock + 5 + false + 1000000 + 50 + 0 + + + BreakoutBoard/HarpSyncInput + 12 + false + Breakout + + + BreakoutBoard/MemoryMonitor + 10 + false + 10 + + + + + + Headstage64 + + Headstage64/Rhd2164 + 256 + false + Dsp146mHz + Low100mHz + High10000Hz + + + Headstage64/Bno055 + 257 + false + + + Headstage64/TS4231V1 + 258 + true + + + Headstage64/Headstage64ElectricalStimulator + 259 + + + Headstage64/Headstage64OpticalStimulator + 260 + + PortA + + + + + + + + 1024 + 2048 + + + + + Headstage64/TS4231V1 + + 0 + 0 + 0 + + + 1 + 0 + 0 + + + + + + + + NaN + NaN + NaN + 1 + NaN + NaN + NaN + 1 + NaN + NaN + NaN + 1 + NaN + NaN + NaN + 1 + + NaN + NaN + NaN + + + + NaN + NaN + NaN + 1 + NaN + NaN + NaN + 1 + NaN + NaN + NaN + 1 + NaN + NaN + NaN + 1 + + NaN + NaN + NaN + + + + + + + Position + + + Position + + + + + + + + + + + + \ No newline at end of file