The device is based on an open-top mixing and viewing chamber machined out of a 57×81×19 mm tall block of Teflon (Fig. 1B). The chamber was created by drilling a 15.5 mm diameter by 15 mm deep hole into the center of the block (Fig. 1A). The hole’s conical bottom terminates in a 4 mm diameter by 4 mm deep cylinder where four 5 mm diameter orthogonal ports meet (p1 to p4, Fig. 1A, inset). Three of the ports (p1, p2, p3) are connected to computer-controlled peristaltic pumps (Pump 1–3) that connect to Stentor, water and waste containers, respectively. A fifth port (p5) is located 11.6 mm above the lower port (p4) to support a filtering process. Ports p4 and p5 are connected to a pump (Pump 4) with a tube that contains a fine nylon mesh (Rotifer Floss, Reed Mariculture, Campbell, CA) to trap Stentor as the pump circulated water from the bottom to the top of the chamber.
The water container and its associated pump (Pump 2) were used to clean the chamber after a full sequence of dilutions were completed. The filter was backwashed by running Pump 4 in reverse. During Stentor purification, the water container was replaced with an empty container to collect Stentor. The chamber and filter tubing created a total working volume of 5 mL. A fifth pump (Pump 5) was used to inject air to mix the Stentor container. A camera mounted above the chamber captured video of Stentor (Fig. 1C) backlit by an array of white LEDs diffused by the white Teflon block.
The device was controlled by a Raspberry Pi 3 single-board computer running the Raspbian operating system (www.raspberrypi.org), providing a user interface to program and execute Python protocol scripts and video recording. An Arduino single-board microcontroller (www.arduino.cc), controlled by the Raspberry Pi over a USB connection, generated pulses to control the peristaltic pumps to accurately dispense liquids. A laptop (Intel i7-6600U @ 2.6 GHz, 16 G RAM) was used to post-process chamber videos, calculating the average Stentor group speed for each dilution. The image processing code was written in Python (Version 3.0) calling OpenCV library functions.
Computer-controlled syringe pumps are often used to accurately dispense liquids in biological and chemical research. However, they are relatively expensive (>$200), large, often uni-directions (dispense only) and have a fixed volumetric capacity. Inexpensive (~$12) compact peristaltic pumps are available (Gikfun Model AE1207) but are designed for continuous low-precision operation. By applying a sequence of pulses to the peristaltic pump’s DC motors, we were able to dispense small increments of liquid under computer control. By switching the voltage polarity with an H-bridge circuit (Texas Instruments L293D), we could selectively dispense and withdraw liquids or air. We found experimentally that apply 10 pulses of ~110 ms duration would reliably administer or remove 100 uL +/- 5%. To achieve this accuracy, the pulse duration for each individual pump was calibrated for each direction.
We established a design target of injecting 1 mL of spring water containing at least 3 Stentor into the chamber for each chemical concentration. The Stentor stock (Carolina Biological Supply, Burlington, NC) was contaminated with detritus and algae in suspension. We were concerned the Stentor might interact with the contamination (feeding, anchoring, colliding, avoiding), introducing an uncontrolled variable in the toxicology assay. To eliminate this variable, we used the device to remove the contamination. The water container was replaced with an empty collection container and the following protocol script implemented;
1. Mix Stentor by pumping bubbles into the container;
2. Pump 0.2 mL of Stentor into the chamber;
3. Record 20 frames of video and analyze for movement;
4. If the movement detected, pump the chamber content into the collection container, else pump the chamber content into the waste container;
5. Repeat steps #1 to #4 until the Stentor container is empty.
The purification process reduced the initial stock volume by 45%, producing 47.5 mL of purified Stentor stock in under 2 h. Based on visual analysis of the 15 concentration videos used to make figure 1E, 3 of the 148 objects injected into the chamber were identified as algae (2%) and the balance were the Stentor. The level of contamination of the original stock, however, was not quantified.
Household vinegar (Heinz distilled white vinegar from grain 5% acetic acid, 50k ppm) was selected as a benign chemical for prototype testing. The device was initialized to create the first dilution of 25k ppm. The following dilution protocol script was then invoked;
1. Mix Stentor by pumping bubbles into the container;
2. Pump 1 mL of Stentor into the chamber;
3. Mix Stentor and chemical by pumping bubbles into the chamber;
4. Record 60 seconds of video;
5. Remove Stentor from the chamber by running the filter pump;
6. Remove 1 mL of chemical solution from the chamber;
7. Repeat steps #1 to #7, 29 times then stop;
Each dilution iteration mixed 4 parts stock with 1 part dilatant (S:D=4:1), to produce a concentration range of 25k ppm to 46 ppm. Each group of Stentor (step #2) were exposed to only one concentration then expelled (step #5). To conserve Stentor stock, spring water was used for the first 15 dilution iterations, as these high concentrations were previously determined to be lethal to Stentor. The assay (initialization, chemical dilution sequence, and image processing) required less than 1 h to complete.
A dilution series produced a collection of 30 videos (1920×[email protected], 60 s duration), one for each dilution. The average speed of all the moving Stentor in each video was determined by accumulating the movement of each Stentor (in pixels) and converting to microns by the optical gain (1 pix = 14.16 um). The Stentor length ranged from 0.64–1.1 mm, corresponding to 45 to 78 image pixels.
The video analysis algorithm comprised the following steps;
1. Convert color video to grayscale;
2. Create a median frame by calculating the median intensity of 25 randomly selected frames;
3. For each frame detect objects using the following method;
a. Create a difference frame by taking the absolute difference of the current frame and the median frame;
b. Create a binary quantized frame by applying a fixed threshold to the difference frame;
c. Find objects in the binary quantized frame using the OpenCV function cv2.findContours;
d. Save all objects within an acceptable area range.
4. Track all saved objects using the following method;
a. For the first frame, assign every object a unique ID;
b. For each subsequent frame, match object in the current frame with the closest object in the previous frame, carry forward the ID, and save the object ID and location.
5. For all objects tracked, calculate the average speed using the following method;
a. Remove objects that do not substantially move during the duration of the video;
b. Accumulate the distance of all moving objects in the video;
c. Average the accumulated distances by the number of objects and the duration of the video.