Skip to content

Commit

Permalink
Merge branch 'develop' of https://github.com/bonsai-rx/docs-wip into b…
Browse files Browse the repository at this point in the history
  • Loading branch information
bruno-f-cruz committed Jun 21, 2022
2 parents e40bc14 + 0107939 commit 49b295e
Show file tree
Hide file tree
Showing 14 changed files with 126 additions and 79 deletions.
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@ The "develop" branch is specifically created so that contributors can quickly co

When working on an article, first check [the old documentation](https://bonsai-rx.org/docs/) to see what written material might already exist for that topic.

### Including figures

To include a figure or image in an article:
- save your figure or image as a `.svg` file, naming the file using the pattern `[article filename]-[figure name].svg`
- add the figure/image to the **images** folder in this repo

### Standard formatting for operators and operator properties

When referring to operators (also known as nodes in Bonsai), place operator names inside a pair of backticks and double stars (``**`Operator_name`**``) so that the node names render as bold text in code snippet formatting (i.e. **`CameraCapture`**).
Expand Down
26 changes: 20 additions & 6 deletions articles/intro.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,24 @@
## What is Bonsai?

Bonsai is a visual programming environment for creating reactive systems. Open source system that can flexibly integrate across any combination of hardware as needed.
Bonsai is a programming language with the following major features:

## Getting Started
1. **It operates on sequences of elements that are ordered in time.** Elements within these sequences can be any kind of data (images, numbers, strings, etc), and these sequences can be either finite or infinite. Elements within sequences can occur regularly or irregularly and do not need to conform to any underlying clock -- sequences are asynchronous. Most hardware that interacts with the world is asynchronous: a human using a keyboard can produce a sequence of keystrokes, and a webcam can produce a sequence of images, but the time of each keypress and image capture is unrelated. Bonsai addresses this fact at the core of its design and is therefore particularly good at interacting with the physical world.

1. Download Bonsai from [http://bonsai-rx.org](http://bonsai-rx.org).
2. Install **Bonsai - Starter Pack** from the package manager. ![The Bonsai package manager](~/images/packagemanager.png)
3. Click on the `Updates` tab at the top of the screen and install any available upgrades.
4. Read [http://bonsai-rx.org/docs/editor](http://bonsai-rx.org/docs/editor) for an introduction to the user interface.
![A simple sequence](../images/simple-sequence.svg)

_Footnote: If you look at the source code of Bonsai, the technical name for the datatype of all sequences in Bonsai is "IObservable"._

2. **It is (strictly) composable.** Operations on sequences (generation, filtering, combining, etc.) are composed in order to define new sequences. In this way, Bonsai operators are much closer to normal mathematical functions than those in many of the programming languages with which you might already be familiar. In fact, one can think of Bonsai as an algebra that operates on temporal sequences in a similar way to how linear algebra operates on matrices.

3. **It is a visual language.** Operator composition is defined using a graphical tool. To define a composition, operators are linked together in order to form a visual graph (in the mathematical sense), which is called a "workflow" in Bonsai. Each node defines a sequence and each connection gives a node the option to get data from the connected preceding node(s).

The visual language of Bonsai can be read using the following colour code:

### How to read Bonsai code

The visual language of Bonsai contains the following 4 major colors:

- **Green == Sources.** Sources generate sequences of data and do not require an input connection. Some sources generate infinite sequences (i.e. webcams), while others generate finite sequences (i.e. movie files).
- **Blue == Transforms.** Transforms always have a single input connection. Transforms apply some operation on the elements of the incoming sequence, and every element of the input sequence is transformed into an element in the output sequence, with no changes to order or rate.
- **Orange == Combinators.** Combinators take one or more input sequences and apply some sort of control flow. With a combinator node, you can combine data, monitor various sequences, generate new events, drop events, etc. Most of the reactive operators fall into this category, and most of the complexity of a Bonsai workflow lies in the orange nodes.
- **Purple == Sinks.** Sinks take one sequence as input and output the exact same sequence, but they cause some kind of side effect outside of Bonsai (i.e. save data to a file, turn on or off some hardware, etc). Sinks do not change the elements in a sequence, and therefore can be placed anywhere in a workflow without changing its operation.
1 change: 1 addition & 0 deletions docfx.json
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@
"markdownEngineName": "markdig",
"markdownEngineProperties": {
"markdigExtensions": [
"attributes",
"customcontainers"
]
},
Expand Down
24 changes: 24 additions & 0 deletions images/simple-sequence.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 4 additions & 1 deletion index.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,7 @@ Bonsai is a visual programming language.
## Quick Start


1. Download Bonsai from [http://bonsai-rx.org](http://bonsai-rx.org).
2. Install **Bonsai - Starter Pack** from the package manager. ![The Bonsai package manager](~/images/packagemanager.png)
3. Click on the `Updates` tab at the top of the screen and install any available upgrades.
4. Read [http://bonsai-rx.org/docs/editor](http://bonsai-rx.org/docs/editor) for an introduction to the user interface.
14 changes: 11 additions & 3 deletions templates/html/styles/main.css
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@
}

.workflow > p > img {
margin-top: 12px;
margin-left: 12px;
padding-top: 12px;
padding-left: 12px;
padding-right: 12px;
}

.codeHeader {
Expand All @@ -42,7 +43,6 @@
.codeHeader > .language {
padding: 2px 16px;
flex-grow: 1;
text-transform: uppercase;
line-height: 26px;
}

Expand Down Expand Up @@ -89,4 +89,12 @@
.codeHeader > .action .successful-copy-alert.is-transparent {
opacity: 0;
transition: 500ms opacity ease-in-out;
}

.diagram {
text-align: center;
}

summary {
display: list-item;
}
2 changes: 1 addition & 1 deletion templates/html/styles/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ $(function() {
$("code.hljs").each(function() {
var $this = $(this);
var language = /lang-(.+?)(\s|$)/.exec($this.attr("class"))[1].toUpperCase();
if (language === 'CS') {
if (language === 'CS' || language === 'CSHARP') {
language = "C#";
}
if (language === 'JS') {
Expand Down
6 changes: 3 additions & 3 deletions worksheets/acquisition.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ Audio data is captured at much higher temporal sampling frequencies than video.
- Make sure that the `SamplingFrequency` property of the `AudioWriter` matches the frequency of audio capture.
- Run the workflow for some seconds. Playback the file in Windows Media Player to check that it is a valid audio file.

### **Exercise 4 (Optional):** Saving raw binary waveform data
### **Exercise 4:** Saving raw binary waveform data

![Saving raw binary waveform data](~/images/acquisition-audiobinary.svg)

Expand Down Expand Up @@ -178,7 +178,7 @@ _Describe in your own words what the above modified workflow is doing._
- Run the workflow, point the camera at a moving object and visualize the output of the `Sum` operator. Compare small movements to big movements. What happens to the signal when the object holds perfect still?
- Right-click the `Sum` operator. Select the `Scalar` > `Val0` member from the context menu.

**Note:** The `Sum` operator sums the pixel values across all image colour channels. However, in the case of grayscale binary images, there is only one active channel and its sum is stored in the `Val0` field.
{: .notice--info}
> [!Note]
> The `Sum` operator sums the pixel values across all image colour channels. However, in the case of grayscale binary images, there is only one active channel and its sum is stored in the `Val0` field.
- Record the motion of an object using a `CsvWriter` sink.
32 changes: 16 additions & 16 deletions worksheets/closed-loop.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ The easiest way to measure the latency of a closed-loop system is to use a digit
- Insert a `TimeInterval` operator.
- Right-click on the `TimeInterval` operator and select `Output` > `Interval` > `TotalMilliseconds`.

**Note:** The `TimeInterval` operator measures the interval between consecutive events in an observable sequence using the [high-precision event timer (HPET)](https://en.wikipedia.org/wiki/High_Precision_Event_Timer) in the computer. The HPET has a frequency of at least 10MHz, allowing us to accurately time intervals with sub-microsecond precision.
{: .notice--info}
> [!Note]
> The `TimeInterval` operator measures the interval between consecutive events in an observable sequence using the [high-precision event timer (HPET)](https://en.wikipedia.org/wiki/High_Precision_Event_Timer) in the computer. The HPET has a frequency of at least 10MHz, allowing us to accurately time intervals with sub-microsecond precision.
- Run the workflow and measure the round-trip time between digital input messages.

Expand All @@ -38,22 +38,22 @@ The easiest way to measure the latency of a closed-loop system is to use a digit
- Insert a `Crop` transform.
- Run the workflow and set the `RegionOfInterest` property to a small area around the LED.

**Hint:** You can use the visual editor for an easier calibration. While the workflow is running, right-click on the `Crop` transform and select `Show Default Editor` from the context menu or click in the small button with ellipsis that appears when you select the `RegionOfInterest` property.
{: .notice--info}
> [!Tip]
> You can use the visual editor for an easier calibration. While the workflow is running, right-click on the `Crop` transform and select `Show Default Editor` from the context menu or click in the small button with ellipsis that appears when you select the `RegionOfInterest` property.
- Insert a `Sum (Dsp)` transform and select the `Val2` field from the output.

**Note:** The `Sum (Dsp)` operator adds the value of all the pixels in the image together, across all the color channels. Assuming the default BGR format, the result of summing all the pixels in the Red channel of the image will be stored in `Val2`. `Val0` and `Val1` would store the Blue and Green values, respectively. If you are using an LED with a color other than Red, please select the output field accordingly.
{: .notice--info}
> [!Note]
> The `Sum (Dsp)` operator adds the value of all the pixels in the image together, across all the color channels. Assuming the default BGR format, the result of summing all the pixels in the Red channel of the image will be stored in `Val2`. `Val0` and `Val1` would store the Blue and Green values, respectively. If you are using an LED with a color other than Red, please select the output field accordingly.
- Insert a `GreaterThan` transform.
- Insert a `BitwiseNot` transform.
- Insert a `DigitalOutput` sink and configure its `Pin` property to pin 13.
- Run the workflow and use the visualizer of the `Sum` operator to choose an appropriate threshold for `GreaterThan`. When connected to pin 13, the LED should flash a couple of times when the Arduino is first connected.
- Insert a [`DistinctUntilChanged`](https://bonsai-rx.org/docs/operators/distinctuntilchanged){:target="\_blank"} operator after the `BitwiseNot` transform.

**Note:** The `DistinctUntilChanged` operator filters consecutive duplicate items from an observable sequence. In this case, we want to change the value of the LED only when the threshold output changes from `LOW` to `HIGH`, or vice-versa. This will let us measure correctly the latency between detecting a change in the input and measuring the response to that change.
{: .notice--info}
> [!Note]
> The `DistinctUntilChanged` operator filters consecutive duplicate items from an observable sequence. In this case, we want to change the value of the LED only when the threshold output changes from `LOW` to `HIGH`, or vice-versa. This will let us measure correctly the latency between detecting a change in the input and measuring the response to that change.
- Insert the `TimeInterval` operator and select `Output` > `Interval` > `TotalMilliseconds`.
- Run the workflow and measure the round-trip time between LED triggers.
Expand All @@ -78,8 +78,8 @@ _Given the measurements obtained in Exercise 2, what would you estimate is the *
- Run the workflow and verify that entering the region of interest triggers the Arduino LED.
- **Optional:** Replace the `Crop` transform by a `CropPolygon` to allow for non-rectangular regions.

**Note:** The `CropPolygon` operator uses the `Regions` property to define multiple, possibly non-rectangular regions. The visual editor is similar to `Crop`, where you draw a rectangular box. However, in `CropPolygon` you can move the corners of the box by right-clicking _inside_ the box and dragging the cursor to the new position. You can add new points by double-clicking with the left mouse button, and delete points by double-clicking with the right mouse button. You can delete regions by pressing the `Del` key and cycle through selected regions by pressing the `Tab` key.
{: .notice--info}
> [!Note]
> The `CropPolygon` operator uses the `Regions` property to define multiple, possibly non-rectangular regions. The visual editor is similar to `Crop`, where you draw a rectangular box. However, in `CropPolygon` you can move the corners of the box by right-clicking _inside_ the box and dragging the cursor to the new position. You can add new points by double-clicking with the left mouse button, and delete points by double-clicking with the right mouse button. You can delete regions by pressing the `Del` key and cycle through selected regions by pressing the `Tab` key.
### **Exercise 4:** Modulating stimulus intensity based on distance to a point

Expand All @@ -102,16 +102,16 @@ The result of the `Subtract` operator will be a vector pointing from the target
- Insert an `ExpressionTransform` operator. This node allows you to write small mathematical and logical expressions to transform input values.
- Right-click on the `ExpressionTransform` operator and select `Show Default Editor`. Set the expression to `Math.Sqrt(X*X + Y*Y)`.

**Note:** Inside the `Expression` editor you can access any field of the input by name. In this case `X` and `Y` represent the corresponding fields of the `Point2f` data type. You can check which fields are available by right-clicking the previous node. You can use all the normal arithmetical and logical operators as well as the mathematical functions available in the [`Math`](<https://msdn.microsoft.com/en-us/library/system.math(v=vs.110).aspx>) type. The default expression `it` means "input" and represents the input value itself.
{: .notice--info}
> [!Note]
> Inside the `Expression` editor you can access any field of the input by name. In this case `X` and `Y` represent the corresponding fields of the `Point2f` data type. You can check which fields are available by right-clicking the previous node. You can use all the normal arithmetical and logical operators as well as the mathematical functions available in the [`Math`](<https://msdn.microsoft.com/en-us/library/system.math(v=vs.110).aspx>) type. The default expression `it` means "input" and represents the input value itself.
- Connect the `ExpressionTransform` operator to the externalized `Amplitude` property.
- Run the workflow and verify that stimulus intensity is modulated by the distance of the object to the target point.
- **Optional:** Modulate the `Frequency` property instead of `Amplitude`.
- **Optional:** Use the `Rescale` operator to adjust the gain of the modulation by configuring the `Min`, `Max`, `RangeMax` and `RangeMin` properties. Set the `RescaleType` property to `Clamp` to restrict the output values to an allowed range.

**Note:** You can specify inverse relationships using `Rescale` if you set the _maximum_ input value to the `Min` property, and the _minimum_ input value to the `Max` property. In this case, a small distance will generate a large output, and a large distance will produce a small output.
{: .notice--info}
> [!Note]
> You can specify inverse relationships using `Rescale` if you set the _maximum_ input value to the `Min` property, and the _minimum_ input value to the `Max` property. In this case, a small distance will generate a large output, and a large distance will produce a small output.
### **Exercise 5:** Triggering a digital line based on distance between objects

Expand Down Expand Up @@ -171,8 +171,8 @@ We now want to map our negative centroid to the `Translation` property of `Affin
- Open the `PropertyMappings` editor and add a new mapping to the `Translation` property.
- Run the workflow. Verify the object is always placed at position (0,0). What is the problem?

**Note:** Generally for image coordinates, (0,0) is at the top-left corner, and the center will be at coordinates (width/2, height/2), usually (320,240) for images with 640 x 480 resolution.
{: .notice--info}
> [!Note]
> Generally for image coordinates, (0,0) is at the top-left corner, and the center will be at coordinates (width/2, height/2), usually (320,240) for images with 640 x 480 resolution.
- Insert an `Add` transform. This will add a fixed offset to the point. Configure the `Value` property with an offset that will place the object at the image centre, e.g. (320,240).
- Run the workflow, and verify the output of `WarpAffine` is now a video which is always centred on the tracked object.
Expand Down
4 changes: 2 additions & 2 deletions worksheets/scripting.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ Install the following:
3. [C# extension](https://marketplace.visualstudio.com/items?itemName=ms-dotnettools.csharp) from the VS Code extensions menu.
4. [.NET Framework 4.7.2 Developer Pack](https://dotnet.microsoft.com/download/dotnet-framework/net472).

_You might need to reboot your machine after installing these components._
{: .notice--info}
> [!Warning]
> You might need to reboot your machine after installing these components.
## Random Dot Kinematogram

Expand Down
Loading

0 comments on commit 49b295e

Please sign in to comment.