Programmable Microfluidics Bill Thies Joint work with J. P

Slides:



Advertisements
Similar presentations
Computer Abstractions and Technology
Advertisements

Computer-Aided Design for Microfluidic Chips Based on Multilayer Soft Lithography Nada Amin 1, William Thies 2, Saman Amarasinghe 1 1 Massachusetts Institute.
Chapter 5: Computer Systems Organization Invitation to Computer Science, Java Version, Third Edition.
Monolithic Microfabricated Valves and Pumps by Multilayer Soft Lithography EECE 491C Unger et al. (Quake group, CALTECH) Science, 2000.
Microfluidic Biochips: Design, Programming, and Optimization Bill Thies Joint work with Vaishnavi Ananthanarayanan, J.P. Urbanski, Nada Amin, David.
Chapter 2: Impact of Machine Architectures What is the Relationship Between Programs, Programming Languages, and Computers.
C++ Programming: From Problem Analysis to Program Design, Third Edition Chapter 1: An Overview of Computers and Programming Languages C++ Programming:
Programmable Microfluidics Bill Thies Computer Science and Artificial Intelligence Laboratory Massachusetts Institute of Technology UC Berkeley – October.
Bringing Programmability to Experimental Biology Bill Thies Joint work with Vaishnavi Ananthanarayanan, J.P. Urbanski, Nada Amin, David Craig, Jeremy Gunawardena,
An Introduction Chapter Chapter 1 Introduction2 Computer Systems  Programmable machines  Hardware + Software (program) HardwareProgram.
Programmable Microfluidics Using Soft Lithography J.P. Urbanski Advisor: Todd Thorsen Hatsopoulos Microfluidics Lab, MIT January 25/2006.
Algorithms and Programming
Chapter 5: Computer Systems Organization Invitation to Computer Science, Java Version, Third Edition.
Programmable Microfluidics William Thies*, J.P. Urbanski †, Mats Cooper †, David Wentzlaff*, Todd Thorsen †, and Saman Amarasinghe * * Computer Science.
C++ Programming: From Problem Analysis to Program Design, Third Edition Chapter 1: An Overview of Computers and Programming Languages.
1 Text Reference: Warford. 2 Computer Architecture: The design of those aspects of a computer which are visible to the programmer. Architecture Organization.
Chapter 4 MARIE: An Introduction to a Simple Computer.
Data Structures and Algorithms Dr. Tehseen Zia Assistant Professor Dept. Computer Science and IT University of Sargodha Lecture 1.
Abstraction Layers for Scalable Microfluidic Biocomputers William Thies*, J.P. Urbanski †, Todd Thorsen † and Saman Amarasinghe * * Computer Science and.
Towards Programmable Microfluidics William Thies
Wajid Minhass, Paul Pop, Jan Madsen Technical University of Denmark
DR. SIMING LIU SPRING 2016 COMPUTER SCIENCE AND ENGINEERING UNIVERSITY OF NEVADA, RENO Session 2 Computer Organization.
INTRODUCTION TO COMPUTER PROGRAMMING(IT-303) Basics.
Review A program is… a set of instructions that tell a computer what to do. Programs can also be called… software. Hardware refers to… the physical components.
Some of the utilities associated with the development of programs. These program development tools allow users to write and construct programs that the.
Operating System Concepts with Java – 7 th Edition, Nov 15, 2006 Silberschatz, Galvin and Gagne ©2007 Chapter 0: Historical Overview.
Introduction to the FPGA and Labs
Computers’ Basic Organization
Kai Li, Allen D. Malony, Sameer Shende, Robert Bell
Installing Java on a Home machine
Java Programming: From the Ground Up
Integrated Circuits.
ES C263 Microprocessor Programming and Interfacing
Chapter 1: An Overview of Computers and Programming Languages
Computer Architecture & Operations I
Biological System – Yeast Pheromone Signal Transduction Pathway
COMPUTER ORGANIZATION & ASSEMBLY LANGUAGE
Paper Microfluidic Devices
Introduction to Operating System (OS)
Architecture & Organization 1
Chapter 1: An Overview of Computers and Programming Languages
Hierarchical Architecture
C++ Programming: From Problem Analysis to Program Design
CSCI/CMPE 3334 Systems Programming
Installing Java on a Home machine
Introduction to cosynthesis Rabi Mahapatra CSCE617
Unit# 9: Computer Program Development
Graph Paper Programming
Architecture & Organization 1
BIC 10503: COMPUTER ARCHITECTURE
Lesson 2 Programming constructs – Algorithms – Scratch – Variables Intro.
Microfluidic Biochips
The performance requirements for DSP applications continue to grow and the traditional solutions do not adequately address this new challenge Paradigm.
Chapter 5: Computer Systems Organization
Chapter 1 Introduction(1.1)
Analysis models and design models
Chapter 1 Introduction.
HIGH LEVEL SYNTHESIS.
MARIE: An Introduction to a Simple Computer
Text by: Lambert and Osborne
Introduction to Computer Programming
Introduction to Microprocessor Programming
Introduction to Data Structure
Introduction to Computer Systems
Combinational Circuits
Introduction to Virtual Machines
ECE 352 Digital System Fundamentals
Introduction to Virtual Machines
Combinational Circuits
Computer Systems An Introducton.
Presentation transcript:

Programmable Microfluidics Bill Thies Joint work with J. P Programmable Microfluidics Bill Thies Joint work with J.P. Urbanski†, David Craig†, Nada Amin*, Todd Thorsen† and Saman Amarasinghe* * Computer Science and Artificial Intelligence Laboratory Hatsopoulos Microfluids Laboratory Massachusetts Institute of Technology Pennsylvania State University – April 13, 2007 Thank you. It’s great to be able to talk today about some interdisciplinary work that we’ve been doing in our lab. This is a collaboration between the computer science department (where I sit) and the microfluidics laboratory at MIT. Our goal is to leverage recent advances in microfluidic chips to build a platform for automatically executing a broad class of biology experiments. Our approach has both a hardware and software component, designing a new generation of chips and also a new generation of programming languages and compilers to enable biologists to easily utilize the technology. Looking forward, we think that just as programmability was the key to leveraging the computer revolution, that programmability will also be key in realizing the potential of the biology revolution. This project started when we discovered the capabilities of microfluidic chips… †

Microfluidic Chips Idea: a whole biology lab on a single chip Input/output Sensors: luminescence, pH, glucose, etc. Actuators: mixing, PCR, electrophoresis, cell lysis, etc. Benefits: Small sample volumes High throughput Geometrical manipulation Applications: Biochemistry - Cell biology Biological computing 1 mm 10x real-time [Livstone/Landweber] [van Noort] [Grover/Mathies] [McCaskill] [Gehani/Reif] [Farfel/Stefanovic] [Somei/Kaneda/Fujii/Murata]

Moore’s Law of Microfluidics: Valve Density Doubles Every 4 Months Source: Fluidigm Corporation (http://www.fluidigm.com/images/mlaw_lg.jpg)

Moore’s Law of Microfluidics: Valve Density Doubles Every 4 Months (From Fluidigm website: ”After dividing the sample into 10,000 parts-an estimated 14.4 copies of the wild type per reaction chamber-the mutant alleles could be readily identified through amplification.“ Source: Fluidigm Corporation (http://www.fluidigm.com/didIFC.htm)

Current Practice: Expose Gate-Level Details to Users Manually map experiment to the valves of the device Using Labview or custom C interface Given a new device, start over and do mapping again

Our Approach: “Write Once, Run Anywhere” Example: Gradient generation Hidden from programmer: Location of fluids Details of mixing, I/O Logic of valve control Timing of chip operations Fluid yellow = input (0); Fluid blue = input(1); for (int i=0; i<=4; i++) { mix(yellow, 1-i/4, blue, i/4); } Will use as running example throughout the talk Decreasing amounts of yellow, increasing amounts of blue 450 Valve Operations

Our Approach: “Write Once, Run Anywhere” Example: Gradient generation Hidden from programmer: Location of fluids Details of mixing, I/O Logic of valve control Timing of chip operations Fluid yellow = input (0); Fluid blue = input(1); for (int i=0; i<=4; i++) { mix(yellow, 1-i/4, blue, i/4); } setValve(0, HIGH); setValve(1, HIGH); setValve(2, LOW); setValve(3, HIGH); setValve(4, LOW); setValve(5, LOW); setValve(6, HIGH); setValve(7, LOW); setValve(8, LOW); setValve(9, HIGH); setValve(10, LOW); setValve(11, HIGH); setValve(12, LOW); setValve(13, HIGH); setValve(14, LOW); setValve(15, HIGH); setValve(16, LOW); setValve(17, LOW); setValve(18, LOW); setValve(19, LOW); wait(2000); setValve(14, HIGH); setValve(2, LOW); wait(1000); setValve(4, HIGH); setValve(12, LOW); setValve(16, HIGH); setValve(18, HIGH); setValve(19, LOW); wait(2000); setValve(14, HIGH); setValve(2, LOW); wait(1000); setValve(4, HIGH); setValve(12, LOW); setValve(16, HIGH); setValve(18, HIGH); setValve(19, LOW); setValve(0, LOW); setValve(1, LOW); setValve(2, LOW); setValve(3, HIGH); setValve(4, LOW); setValve(5, HIGH); setValve(6, HIGH); setValve(7, LOW); setValve(8, LOW); setValve(9, HIGH); setValve(10, HIGH); setValve(11, LOW); setValve(12, LOW); setValve(13, LOW); setValve(14, LOW); setValve(15, HIGH); setValve(16, HIGH); setValve(17, LOW); setValve(18, HIGH); setValve(19, LOW); setValve(0, HIGH); setValve(1, HIGH); setValve(2, LOW); setValve(3, HIGH); setValve(4, LOW); setValve(5, LOW); setValve(6, HIGH); setValve(7, LOW); setValve(8, LOW); setValve(9, HIGH); setValve(10, LOW); setValve(11, HIGH); setValve(12, LOW); setValve(13, HIGH); setValve(14, LOW); setValve(15, HIGH); setValve(16, LOW); setValve(17, LOW); setValve(18, LOW); setValve(19, LOW); wait(2000); setValve(14, HIGH); setValve(2, LOW); wait(1000); setValve(4, HIGH); setValve(12, LOW); setValve(16, HIGH); setValve(18, HIGH); setValve(19, LOW); wait(2000); setValve(14, HIGH); setValve(2, LOW); wait(1000); setValve(4, HIGH); setValve(12, LOW); setValve(16, HIGH); setValve(18, HIGH); setValve(19, LOW); setValve(0, LOW); setValve(1, LOW); setValve(2, LOW); setValve(3, HIGH); setValve(4, LOW); setValve(5, HIGH); setValve(6, HIGH); setValve(7, LOW); setValve(8, LOW); setValve(9, HIGH); setValve(10, HIGH); setValve(11, LOW); setValve(12, LOW); setValve(13, LOW); setValve(14, LOW); setValve(15, HIGH); setValve(16, HIGH); setValve(17, LOW); setValve(18, HIGH); setValve(19, LOW); setValve(0, HIGH); setValve(1, HIGH); setValve(2, LOW); setValve(3, HIGH); setValve(4, LOW); setValve(5, LOW); setValve(6, HIGH); setValve(7, LOW); setValve(8, LOW); setValve(9, HIGH); setValve(10, LOW); setValve(11, HIGH); setValve(12, LOW); setValve(13, HIGH); setValve(14, LOW); setValve(15, HIGH); setValve(16, LOW); setValve(17, LOW); setValve(18, LOW); setValve(19, LOW); wait(2000); setValve(14, HIGH); setValve(2, LOW); wait(1000); setValve(4, HIGH); setValve(12, LOW); setValve(16, HIGH); setValve(18, HIGH); setValve(19, LOW); wait(2000); setValve(14, HIGH); setValve(2, LOW); wait(1000); setValve(4, HIGH); setValve(12, LOW); setValve(16, HIGH); setValve(18, HIGH); setValve(19, LOW); setValve(0, LOW); setValve(1, LOW); setValve(2, LOW); setValve(3, HIGH); setValve(4, LOW); setValve(5, HIGH); setValve(6, HIGH); setValve(7, LOW); setValve(8, LOW); setValve(9, HIGH); setValve(10, HIGH); setValve(11, LOW); setValve(12, LOW); setValve(13, LOW); setValve(14, LOW); setValve(15, HIGH); setValve(16, HIGH); setValve(17, LOW); setValve(18, HIGH); setValve(19, LOW); setValve(0, HIGH); setValve(1, HIGH); setValve(2, LOW); setValve(3, HIGH); setValve(4, LOW); setValve(5, LOW); setValve(6, HIGH); setValve(7, LOW); setValve(8, LOW); setValve(9, HIGH); setValve(10, LOW); setValve(11, HIGH); setValve(12, LOW); setValve(13, HIGH); setValve(14, LOW); setValve(15, HIGH); setValve(16, LOW); setValve(17, LOW); setValve(18, LOW); setValve(19, LOW); wait(2000); setValve(14, HIGH); setValve(2, LOW); wait(1000); setValve(4, HIGH); setValve(12, LOW); setValve(16, HIGH); setValve(18, HIGH); setValve(19, LOW); wait(2000); setValve(14, HIGH); setValve(2, LOW); wait(1000); setValve(4, HIGH); setValve(12, LOW); setValve(16, HIGH); setValve(18, HIGH); setValve(19, LOW); setValve(0, LOW); setValve(1, LOW); setValve(2, LOW); setValve(3, HIGH); setValve(4, LOW); setValve(5, HIGH); setValve(6, HIGH); setValve(7, LOW); setValve(8, LOW); setValve(9, HIGH); setValve(10, HIGH); setValve(11, LOW); setValve(12, LOW); setValve(13, LOW); setValve(14, LOW); setValve(15, HIGH); setValve(16, HIGH); setValve(17, LOW); setValve(18, HIGH); setValve(19, LOW); setValve(0, HIGH); setValve(1, HIGH); setValve(2, LOW); setValve(3, HIGH); setValve(4, LOW); setValve(5, LOW); setValve(6, HIGH); setValve(7, LOW); setValve(8, LOW); setValve(9, HIGH); setValve(10, LOW); setValve(11, HIGH); setValve(12, LOW); setValve(13, HIGH); setValve(14, LOW); setValve(15, HIGH); setValve(16, LOW); setValve(17, LOW); setValve(18, LOW); setValve(19, LOW); wait(2000); setValve(14, HIGH); setValve(2, LOW); wait(1000); setValve(4, HIGH); setValve(12, LOW); setValve(16, HIGH); setValve(18, HIGH); setValve(19, LOW); wait(2000); setValve(14, HIGH); setValve(2, LOW); wait(1000); setValve(4, HIGH); setValve(12, LOW); setValve(16, HIGH); setValve(18, HIGH); setValve(19, LOW); setValve(0, LOW); setValve(1, LOW); setValve(2, LOW); setValve(3, HIGH); setValve(4, LOW); setValve(5, HIGH); setValve(6, HIGH); setValve(7, LOW); setValve(8, LOW); setValve(9, HIGH); setValve(10, HIGH); setValve(11, LOW); setValve(12, LOW); setValve(13, LOW); setValve(14, LOW); setValve(15, HIGH); setValve(16, HIGH); setValve(17, LOW); setValve(18, HIGH); setValve(19, LOW); setValve(0, HIGH); setValve(1, HIGH); setValve(2, LOW); setValve(3, HIGH); setValve(4, LOW); setValve(5, LOW); setValve(6, HIGH); setValve(7, LOW); setValve(8, LOW); setValve(9, HIGH); setValve(10, LOW); setValve(11, HIGH); setValve(12, LOW); setValve(13, HIGH); setValve(14, LOW); setValve(15, HIGH); setValve(16, LOW); setValve(17, LOW); setValve(18, LOW); setValve(19, LOW); wait(2000); setValve(14, HIGH); setValve(2, LOW); wait(1000); setValve(4, HIGH); setValve(12, LOW); setValve(16, HIGH); setValve(18, HIGH); setValve(19, LOW); wait(2000); setValve(14, HIGH); setValve(2, LOW); wait(1000); setValve(4, HIGH); setValve(12, LOW); setValve(16, HIGH); setValve(18, HIGH); setValve(19, LOW); setValve(0, LOW); setValve(1, LOW); setValve(2, LOW); setValve(3, HIGH); setValve(4, LOW); setValve(5, HIGH); setValve(6, HIGH); setValve(7, LOW); setValve(8, LOW); setValve(9, HIGH); setValve(10, HIGH); setValve(11, LOW); setValve(12, LOW); setValve(13, LOW); setValve(14, LOW); setValve(15, HIGH); setValve(16, HIGH); setValve(17, LOW); setValve(18, HIGH); setValve(19, LOW); setValve(0, HIGH); setValve(1, HIGH); setValve(2, LOW); setValve(3, HIGH); setValve(4, LOW); setValve(5, LOW); setValve(6, HIGH); setValve(7, LOW); setValve(8, LOW); setValve(9, HIGH); setValve(10, LOW); setValve(11, HIGH); setValve(12, LOW); setValve(13, HIGH); setValve(14, LOW); setValve(15, HIGH); setValve(16, LOW); setValve(17, LOW); setValve(18, LOW); setValve(19, LOW); wait(2000); setValve(14, HIGH); setValve(2, LOW); wait(1000); setValve(4, HIGH); setValve(12, LOW); setValve(16, HIGH); setValve(18, HIGH); setValve(19, LOW); wait(2000); setValve(14, HIGH); setValve(2, LOW); wait(1000); setValve(4, HIGH); setValve(12, LOW); setValve(16, HIGH); setValve(18, HIGH); setValve(19, LOW); setValve(0, LOW); setValve(1, LOW); setValve(2, LOW); setValve(3, HIGH); setValve(4, LOW); setValve(5, HIGH); setValve(6, HIGH); setValve(7, LOW); setValve(8, LOW); setValve(9, HIGH); setValve(10, HIGH); setValve(11, LOW); setValve(12, LOW); setValve(13, LOW); setValve(14, LOW); setValve(15, HIGH); setValve(16, HIGH); setValve(17, LOW); setValve(18, HIGH); setValve(19, LOW); setValve(0, HIGH); setValve(1, HIGH); setValve(2, LOW); setValve(3, HIGH); setValve(4, LOW); setValve(5, LOW); setValve(6, HIGH); setValve(7, LOW); setValve(8, LOW); setValve(9, HIGH); setValve(10, LOW); setValve(11, HIGH); setValve(12, LOW); setValve(13, HIGH); setValve(14, LOW); setValve(15, HIGH); setValve(16, LOW); setValve(17, LOW); setValve(18, LOW); setValve(19, LOW); wait(2000); setValve(14, HIGH); setValve(2, LOW); wait(1000); setValve(4, HIGH); setValve(12, LOW); setValve(16, HIGH); setValve(18, HIGH); setValve(19, LOW); wait(2000); setValve(14, HIGH); setValve(2, LOW); wait(1000); setValve(4, HIGH); setValve(12, LOW); setValve(16, HIGH); setValve(18, HIGH); setValve(19, LOW); setValve(0, LOW); setValve(1, LOW); setValve(2, LOW); setValve(3, HIGH); setValve(4, LOW); setValve(5, HIGH); setValve(6, HIGH); setValve(7, LOW); setValve(8, LOW); setValve(9, HIGH); setValve(10, HIGH); setValve(11, LOW); setValve(12, LOW); setValve(13, LOW); setValve(14, LOW); setValve(15, HIGH); setValve(16, HIGH); setValve(17, LOW); setValve(18, HIGH); setValve(19, LOW); 450 Valve Operations

Fluidic Abstraction Layers Silicon Analog Protocol Description Language - readable code with high-level mixing ops C Fluidic Instruction Set Architecture (ISA) - primitives for I/O, storage, transport, mixing x86 Pentium III, Pentium IV chip 1 chip 2 chip 3 Fluidic Hardware Primitives - valves, multiplexers, mixers, latches transistors, registers, …

Fluidic Abstraction Layers Benefits: Portability Division of labor Scalability Expressivity Protocol Description Language - readable code with high-level mixing ops Fluidic Instruction Set Architecture (ISA) - primitives for I/O, storage, transport, mixing chip 1 chip 2 chip 3 Fluidic Hardware Primitives - valves, multiplexers, mixers, latches

Fluidic Abstraction Layers Benefits: Portability Division of labor Scalability Expressivity Protocol Description Language - readable code with high-level mixing ops Fluidic Instruction Set Architecture (ISA) - primitives for I/O, storage, transport, mixing chip 1 chip 2 chip 3 Fluidic Hardware Primitives - valves, multiplexers, mixers, latches

Primitive 1: A Valve (Quake et al.) Control Layer 0. Start with mask of channels Flow Layer

Primitive 1: A Valve (Quake et al.) Control Layer 1. Deposit pattern on silicon wafer Flow Layer

Primitive 1: A Valve (Quake et al.) Control Layer 2. Pour PDMS over mold - polydimexylsiloxane: “soft lithography” Thick layer (poured) Thin layer (spin-coated) Flow Layer

Primitive 1: A Valve (Quake et al.) Control Layer 3. Bake at 80° C (primary cure), then release PDMS from mold Flow Layer

Primitive 1: A Valve (Quake et al.) Control Layer 4a. Punch hole in control channel 4b. Attach flow layer to glass slide Flow Layer

Primitive 1: A Valve (Quake et al.) Control Layer 5. Align flow layer over control layer Flow Layer

Primitive 1: A Valve (Quake et al.) Control Layer 6. Bake at 80° C (secondary cure) Flow Layer

Primitive 1: A Valve (Quake et al.) 7. When pressure is high, control channel pinches flow channel to form a valve Control Layer pressure actuator Note that this can be done in university facilities in about two days, with marginal cost of less than a dollar. Flow Layer

Primitive 2: A Multiplexer (Thorsen et al.) Bit 2 Bit 1 Bit 0 flow layer control layer 1 1 1 Control lines can cross flow lines - Only thick parts make valves Output 7 Output 6 Output 5 Input Output 4 Logic is not complimentary To control n flow lines, need 2 log2 n control lines Output 3 Output 2 Control lines can cross flow lines - Only thick parts make valves Logic is not complimentary To control n flow lines, need 2 log2 n control lines Output 1 Output 0

Primitive 2: A Multiplexer (Thorsen et al.) Bit 2 Bit 1 Bit 0 flow layer control layer 1 1 1 Control lines can cross flow lines - Only thick parts make valves Output 7 Output 6 Output 5 Input Output 4 Logic is not complimentary To control n flow lines, need 2 log2 n control lines Output 3 Output 2 Output 1 Output 0 Example: select 3 = 011

Primitive 2: A Multiplexer (Thorsen et al.) Bit 2 Bit 1 Bit 0 flow layer control layer 1 1 1 Control lines can cross flow lines - Only thick parts make valves Output 7 Output 6 Output 5 Input Output 4 Logic is not complimentary To control n flow lines, need 2 log2 n control lines Output 3 Output 2 Output 1 Output 0 Example: select 3 = 011

Primitive 2: A Multiplexer (Thorsen et al.) Bit 2 Bit 1 Bit 0 flow layer control layer 1 1 1 Control lines can cross flow lines - Only thick parts make valves Output 7 Output 6 Output 5 Input Output 4 Logic is not complimentary To control n flow lines, need 2 log2 n control lines Output 3 Output 2 Output 1 Output 0 Example: select 3 = 011

Primitive 3: A Mixer (Quake et al.)

Primitive 3: A Mixer (Quake et al.) 1. Load sample on top

Primitive 3: A Mixer (Quake et al.) 1. Load sample on top 2. Load sample on bottom

Primitive 3: A Mixer (Quake et al.) 1. Load sample on top 2. Load sample on bottom 3. Peristaltic pumping Rotary Mixing

Primitive 4: A Latch (Our contribution) Purpose: align sample with specific location on device Examples: end of storage cell, end of mixer, middle of sensor Latches are implemented as a partially closed valve Background flow passes freely Aqueous samples are caught Sample Latch

Fluidic Abstraction Layers Protocol Description Language - readable code with high-level mixing ops Fluidic Instruction Set Architecture (ISA) - primitives for I/O, storage, transport, mixing In an ideal world, would have instruction for every bio operation chip 1 chip 2 chip 3 Fluidic Hardware Primitives - valves, multiplexers, mixers, latches

Abstraction 1: Digital Architecture Recent chips can control independent fluid samples Droplet-based samples Continuous-flow samples Microfluidic latches In abstract machine, all samples have unit volume Input/output a sample Store a sample Operate on a sample [Fair et al.] [Urbanski et al.] [Urbanski et al.] Microfluidics different in that basically analog - fluids can flow anywhere, mix together, etc.

Abstraction 2: Mix Instruction Microfluidic chips have various mixing technologies Electrokinetic mixing Droplet mixing Rotary mixing Common attributes: Ability to mix two samples in equal proportions, store result Fluidic ISA: mix (int src1, int src2, int dst) Ex: mix(1, 2, 3) To allow for lossy transport, only 1 unit of mixture retained [Levitan et al.] [Fair et al.] [Quake et al.] Storage Cells 1 2 3 4 Mixer

Gradient Generation in Fluidic ISA setValve(0, HIGH); setValve(1, HIGH); setValve(2, LOW); setValve(3, HIGH); setValve(4, LOW); setValve(5, LOW); setValve(6, HIGH); setValve(7, LOW); setValve(8, LOW); setValve(9, HIGH); setValve(10, LOW); setValve(11, HIGH); setValve(12, LOW); setValve(13, HIGH); setValve(14, LOW); setValve(15, HIGH); setValve(16, LOW); setValve(17, LOW); setValve(18, LOW); setValve(19, LOW); wait(2000); setValve(14, HIGH); setValve(2, LOW); wait(1000); setValve(4, HIGH); setValve(12, LOW); setValve(16, HIGH); setValve(18, HIGH); setValve(19, LOW); setValve(0, HIGH); setValve(1, HIGH); setValve(2, LOW); setValve(3, HIGH); setValve(4, LOW); setValve(5, LOW); setValve(6, HIGH); setValve(7, LOW); setValve(8, LOW); setValve(9, HIGH); setValve(10, LOW); setValve(11, HIGH); setValve(12, LOW); setValve(13, HIGH); setValve(14, LOW); setValve(15, HIGH); setValve(16, LOW); setValve(17, LOW); setValve(18, LOW); setValve(19, LOW); wait(2000); setValve(14, HIGH); setValve(2, LOW); wait(1000); setValve(4, HIGH); setValve(12, LOW); setValve(16, HIGH); setValve(18, HIGH); setValve(19, LOW); wait(2000); setValve(14, HIGH); setValve(2, LOW); wait(1000); setValve(4, HIGH); setValve(12, LOW); setValve(16, HIGH); setValve(18, HIGH); setValve(19, LOW); setValve(0, LOW); setValve(1, LOW); setValve(2, LOW); setValve(3, HIGH); setValve(4, LOW); setValve(5, HIGH); setValve(6, HIGH); setValve(7, LOW); setValve(8, LOW); setValve(9, HIGH); setValve(10, HIGH); setValve(11, LOW); setValve(12, LOW); setValve(13, LOW); setValve(14, LOW); setValve(15, HIGH); setValve(16, HIGH); setValve(17, LOW); setValve(18, HIGH); setValve(19, LOW); setValve(0, HIGH); setValve(1, HIGH); setValve(2, LOW); setValve(3, HIGH); setValve(4, LOW); setValve(5, LOW); setValve(6, HIGH); setValve(7, LOW); setValve(8, LOW); setValve(9, HIGH); setValve(10, LOW); setValve(11, HIGH); setValve(12, LOW); setValve(13, HIGH); setValve(14, LOW); setValve(15, HIGH); setValve(16, LOW); setValve(17, LOW); setValve(18, LOW); setValve(19, LOW); wait(2000); setValve(14, HIGH); setValve(2, LOW); wait(1000); setValve(4, HIGH); setValve(12, LOW); setValve(16, HIGH); setValve(18, HIGH); setValve(19, LOW); wait(2000); setValve(14, HIGH); setValve(2, LOW); wait(1000); setValve(4, HIGH); setValve(12, LOW); setValve(16, HIGH); setValve(18, HIGH); setValve(19, LOW); setValve(0, LOW); setValve(1, LOW); setValve(2, LOW); setValve(3, HIGH); setValve(4, LOW); setValve(5, HIGH); setValve(6, HIGH); setValve(7, LOW); setValve(8, LOW); setValve(9, HIGH); setValve(10, HIGH); setValve(11, LOW); setValve(12, LOW); setValve(13, LOW); setValve(14, LOW); setValve(15, HIGH); setValve(16, HIGH); setValve(17, LOW); setValve(18, HIGH); setValve(19, LOW); setValve(0, HIGH); setValve(1, HIGH); setValve(2, LOW); setValve(3, HIGH); setValve(4, LOW); setValve(5, LOW); setValve(6, HIGH); setValve(7, LOW); setValve(8, LOW); setValve(9, HIGH); setValve(10, LOW); setValve(11, HIGH); setValve(12, LOW); setValve(13, HIGH); setValve(14, LOW); setValve(15, HIGH); setValve(16, LOW); setValve(17, LOW); setValve(18, LOW); setValve(19, LOW); wait(2000); setValve(14, HIGH); setValve(2, LOW); wait(1000); setValve(4, HIGH); setValve(12, LOW); setValve(16, HIGH); setValve(18, HIGH); setValve(19, LOW); wait(2000); setValve(14, HIGH); setValve(2, LOW); wait(1000); setValve(4, HIGH); setValve(12, LOW); setValve(16, HIGH); setValve(18, HIGH); setValve(19, LOW); setValve(0, LOW); setValve(1, LOW); setValve(2, LOW); setValve(3, HIGH); setValve(4, LOW); setValve(5, HIGH); setValve(6, HIGH); setValve(7, LOW); setValve(8, LOW); setValve(9, HIGH); setValve(10, HIGH); setValve(11, LOW); setValve(12, LOW); setValve(13, LOW); setValve(14, LOW); setValve(15, HIGH); setValve(16, HIGH); setValve(17, LOW); setValve(18, HIGH); setValve(19, LOW); setValve(0, HIGH); setValve(1, HIGH); setValve(2, LOW); setValve(3, HIGH); setValve(4, LOW); setValve(5, LOW); setValve(6, HIGH); setValve(7, LOW); setValve(8, LOW); setValve(9, HIGH); setValve(10, LOW); setValve(11, HIGH); setValve(12, LOW); setValve(13, HIGH); setValve(14, LOW); setValve(15, HIGH); setValve(16, LOW); setValve(17, LOW); setValve(18, LOW); setValve(19, LOW); wait(2000); setValve(14, HIGH); setValve(2, LOW); wait(1000); setValve(4, HIGH); setValve(12, LOW); setValve(16, HIGH); setValve(18, HIGH); setValve(19, LOW); wait(2000); setValve(14, HIGH); setValve(2, LOW); wait(1000); setValve(4, HIGH); setValve(12, LOW); setValve(16, HIGH); setValve(18, HIGH); setValve(19, LOW); setValve(0, LOW); setValve(1, LOW); setValve(2, LOW); setValve(3, HIGH); setValve(4, LOW); setValve(5, HIGH); setValve(6, HIGH); setValve(7, LOW); setValve(8, LOW); setValve(9, HIGH); setValve(10, HIGH); setValve(11, LOW); setValve(12, LOW); setValve(13, LOW); setValve(14, LOW); setValve(15, HIGH); setValve(16, HIGH); setValve(17, LOW); setValve(18, HIGH); setValve(19, LOW); setValve(0, HIGH); setValve(1, HIGH); setValve(2, LOW); setValve(3, HIGH); setValve(4, LOW); setValve(5, LOW); setValve(6, HIGH); setValve(7, LOW); setValve(8, LOW); setValve(9, HIGH); setValve(10, LOW); setValve(11, HIGH); setValve(12, LOW); setValve(13, HIGH); setValve(14, LOW); setValve(15, HIGH); setValve(16, LOW); setValve(17, LOW); setValve(18, LOW); setValve(19, LOW); wait(2000); setValve(14, HIGH); setValve(2, LOW); wait(1000); setValve(4, HIGH); setValve(12, LOW); setValve(16, HIGH); setValve(18, HIGH); setValve(19, LOW); wait(2000); setValve(14, HIGH); setValve(2, LOW); wait(1000); setValve(4, HIGH); setValve(12, LOW); setValve(16, HIGH); setValve(18, HIGH); setValve(19, LOW); setValve(0, LOW); setValve(1, LOW); setValve(2, LOW); setValve(3, HIGH); setValve(4, LOW); setValve(5, HIGH); setValve(6, HIGH); setValve(7, LOW); setValve(8, LOW); setValve(9, HIGH); setValve(10, HIGH); setValve(11, LOW); setValve(12, LOW); setValve(13, LOW); setValve(14, LOW); setValve(15, HIGH); setValve(16, HIGH); setValve(17, LOW); setValve(18, HIGH); setValve(19, LOW); setValve(0, HIGH); setValve(1, HIGH); setValve(2, LOW); setValve(3, HIGH); setValve(4, LOW); setValve(5, LOW); setValve(6, HIGH); setValve(7, LOW); setValve(8, LOW); setValve(9, HIGH); setValve(10, LOW); setValve(11, HIGH); setValve(12, LOW); setValve(13, HIGH); setValve(14, LOW); setValve(15, HIGH); setValve(16, LOW); setValve(17, LOW); setValve(18, LOW); setValve(19, LOW); wait(2000); setValve(14, HIGH); setValve(2, LOW); wait(1000); setValve(4, HIGH); setValve(12, LOW); setValve(16, HIGH); setValve(18, HIGH); setValve(19, LOW); wait(2000); setValve(14, HIGH); setValve(2, LOW); wait(1000); setValve(4, HIGH); setValve(12, LOW); setValve(16, HIGH); setValve(18, HIGH); setValve(19, LOW); setValve(0, LOW); setValve(1, LOW); setValve(2, LOW); setValve(3, HIGH); setValve(4, LOW); setValve(5, HIGH); setValve(6, HIGH); setValve(7, LOW); setValve(8, LOW); setValve(9, HIGH); setValve(10, HIGH); setValve(11, LOW); setValve(12, LOW); setValve(13, LOW); setValve(14, LOW); setValve(15, HIGH); setValve(16, HIGH); setValve(17, LOW); setValve(18, HIGH); setValve(19, LOW); setValve(0, HIGH); setValve(1, HIGH); setValve(2, LOW); setValve(3, HIGH); setValve(4, LOW); setValve(5, LOW); setValve(6, HIGH); setValve(7, LOW); setValve(8, LOW); setValve(9, HIGH); setValve(10, LOW); setValve(11, HIGH); setValve(12, LOW); setValve(13, HIGH); setValve(14, LOW); setValve(15, HIGH); setValve(16, LOW); setValve(17, LOW); setValve(18, LOW); setValve(19, LOW); wait(2000); setValve(14, HIGH); setValve(2, LOW); wait(1000); setValve(4, HIGH); setValve(12, LOW); setValve(16, HIGH); setValve(18, HIGH); setValve(19, LOW); wait(2000); setValve(14, HIGH); setValve(2, LOW); wait(1000); setValve(4, HIGH); setValve(12, LOW); setValve(16, HIGH); setValve(18, HIGH); setValve(19, LOW); setValve(0, LOW); setValve(1, LOW); setValve(2, LOW); setValve(3, HIGH); setValve(4, LOW); setValve(5, HIGH); setValve(6, HIGH); setValve(7, LOW); setValve(8, LOW); setValve(9, HIGH); setValve(10, HIGH); setValve(11, LOW); setValve(12, LOW); setValve(13, LOW); setValve(14, LOW); setValve(15, HIGH); setValve(16, HIGH); setValve(17, LOW); setValve(18, HIGH); setValve(19, LOW); setValve(0, HIGH); setValve(1, HIGH); setValve(2, LOW); setValve(3, HIGH); setValve(4, LOW); setValve(5, LOW); setValve(6, HIGH); setValve(7, LOW); setValve(8, LOW); setValve(9, HIGH); setValve(10, LOW); setValve(11, HIGH); setValve(12, LOW); setValve(13, HIGH); setValve(14, LOW); setValve(15, HIGH); setValve(16, LOW); setValve(17, LOW); setValve(18, LOW); setValve(19, LOW); wait(2000); setValve(14, HIGH); setValve(2, LOW); wait(1000); setValve(4, HIGH); setValve(12, LOW); setValve(16, HIGH); setValve(18, HIGH); setValve(19, LOW); wait(2000); setValve(14, HIGH); setValve(2, LOW); wait(1000); setValve(4, HIGH); setValve(12, LOW); setValve(16, HIGH); setValve(18, HIGH); setValve(19, LOW); setValve(0, LOW); setValve(1, LOW); setValve(2, LOW); setValve(3, HIGH); setValve(4, LOW); setValve(5, HIGH); setValve(6, HIGH); setValve(7, LOW); setValve(8, LOW); setValve(9, HIGH); setValve(10, HIGH); setValve(11, LOW); setValve(12, LOW); setValve(13, LOW); setValve(14, LOW); setValve(15, HIGH); setValve(16, HIGH); setValve(17, LOW); setValve(18, HIGH); setValve(19, LOW); input(0, 0); input(1, 1); input(0, 2); mix(1, 2, 3); mix(2, 3, 1); input(1, 3); input(0, 4); mix(3, 4, 2); mix(3, 4, 5); input(1, 4); mix(4, 5, 3); mix(0, 4); abstraction Direct Control - 450 valve actuations - only works on 1 chip Fluidic ISA - 15 instructions - portable across chips

Implementation: Oil-Driven Chip Inputs Storage Cells Background Phase Wash Phase Mixing Chip 1 2 8 Oil — Rotary

Implementation: Oil-Driven Chip mix (S1, S2, D) { 1. Load S1 2. Load S2 3. Rotary mixing 4. Store into D } 50x real-time Inputs Storage Cells Background Phase Wash Phase Mixing Chip 1 2 8 Oil — Rotary

Implementation 2: Air-Driven Chip Inputs Storage Cells Background Phase Wash Phase Mixing Chip 1 2 8 Oil — Rotary Chip 2 4 32 Air Water In channels

Implementation 2: Air-Driven Chip mix (S1, S2, D) { 1. Load S1 2. Load S2 3. Mix / Store into D 4. Wash S1 5. Wash S2 } 50x real-time Inputs Storage Cells Background Phase Wash Phase Mixing Chip 1 2 8 Oil — Rotary Chip 2 4 32 Air Water In channels

Fluidic Abstraction Layers Protocol Description Language - readable code with high-level mixing ops Fluidic Instruction Set Architecture (ISA) - primitives for I/O, storage, transport, mixing chip 1 chip 2 chip 3 Fluidic Hardware Primitives - valves, multiplexers, mixers, latches

Abstraction 1: Managing Fluid Storage Fluid[] out = new Fluid[8]; Fluid yellow, blue, green; out[0] = input(0); yellow = input(0); blue = input(1); green = mix(yellow, blue); out[1] = mix(yellow, green); out[2] = mix(yellow, blue); out[3] = mix(blue, green); out[4] = input(1); input(0, 0); input(1, 1); input(0, 2); mix(1, 2, 3); mix(2, 3, 1); input(1, 3); input(0, 4); mix(3, 4, 2); mix(3, 4, 5); input(1, 4); mix(4, 5, 3); mix(0, 4); Fluidic ISA 1. Storage Management Programmer uses location-independent Fluid variables Runtime system assigns & tracks location of each Fluid Comparable to automatic memory management (e.g., Java)

Abstraction 2: Fluid Re-Generation Fluid[] out = new Fluid[8]; Fluid yellow, blue, green; out[0] = input(0); yellow = input(0); blue = input(1); green = mix(yellow, blue); out[1] = mix(yellow, green); out[2] = mix(yellow, blue); out[3] = mix(blue, green); out[4] = input(1); Fluid[] out = new Fluid[8]; Fluid yellow = input(0); Fluid blue = input(1); Fluid green = mix(yellow, blue); out[0] = yellow; out[1] = mix(yellow, green); out[2] = green; out[3] = mix(blue, green); out[4] = blue; 2. Fluid Re-Generation Programmer may use a Fluid variable multiple times Each time, a physical Fluid is consumed on-chip Runtime system re-generates Fluids from computation history

Abstraction 3: Arbitrary Mixing Fluid[] out = new Fluid[8]; Fluid yellow = input (0); Fluid blue = input (1); out[0] = yellow; out[1] = mix(yellow, 3/4, blue, 1/4); out[2] = mix(yellow, 1/2, blue, 1/2); out[3] = mix(yellow, 1/4, blue, 3/4); out[4] = blue; 3. Arbitrary Mixing Fluid[] out = new Fluid[8]; Fluid yellow = input(0); Fluid blue = input(1); Fluid green = mix(yellow, blue); out[1] = mix(yellow, green); out[2] = green; out[3] = mix(blue, green); 2. Fluid Re-Generation Allows mixing fluids in any proportion, not just 50/50 Fluid mix (Fluid F1, float p1, Fluid f2, float F2)  Returns Fluid that is p1 parts F1 and p2 parts F2 Runtime system translates to 50/50 mixes in Fluidic ISA Note: some mixtures only reachable within error tolerance 

Abstraction 3: Arbitrary Mixing Fluid[] out = new Fluid[8]; Fluid yellow = input (0); Fluid blue = input (1); out[0] = yellow; out[1] = mix(yellow, 3/4, blue, 1/4); out[2] = mix(yellow, 1/2, blue, 1/2); out[3] = mix(yellow, 1/4, blue, 3/4); out[4] = blue; Fluid[] out = new Fluid[8]; Fluid yellow = input (0); Fluid blue = input (1); for (int i=0; i<=4; i++) { out[i] = mix(yellow, 1-i/4, blue, i/4); } 3. Arbitrary Mixing 4. Parameterized Mixing “on the left, exactly mirrors underlying hardware” “on the right, added parameters to mix instruction” Allows mixing fluids in any proportion, not just 50/50 Fluid mix (Fluid F1, float p1, Fluid f2, float F2)  Returns Fluid that is p1 parts F1 and p2 parts F2 Runtime system translates to 50/50 mixes in Fluidic ISA Note: some mixtures only reachable within error tolerance 

BioStream Protocol Language Supports all the abstractions Automatic storage management Re-generation of fluids Arbitrary mixing Implemented as a Java library Allows flexible integration with general-purpose Java code Targets microfluidic chips or auto-generated simulator Fluid yellow = input (0); Fluid blue = input (1); Fluid[] out = new Fluid[8]; for (int i=0; i<=4; i++) { out[i] = mix(yellow, 1-i/4, blue, i/4); } Architecture Description - Double camera(Fluid f); User Code BioStream Library Simulator Generator Fluidic ISA Microfluidic chip Microfluidic simulator

Example: Fixed-pH Reaction Goal: maintain given pH throughout reaction For in-vitro modeling of natural environment Method: periodically test, adjust pH if needed Fluid sample = input (0); Fluid acid = input(1); Fluid base = input(2); do { Fluid pH_test = mix(sample, 0.9, indicator, 0.1); // test pH of sample double pH = test_luminescence(pH_test); if (pH > 7.5) { // if pH too high, add acid sample = mix (sample, 0.9, acid, 0.1); } else if (pH < 6.5) { // if pH too low, add base sample = mix (sample, 0.9, base, 0.1); } wait(60); } while (detect_activity(sample)); “experiments that can RESPOND to their environment in ways that a human wouldn’t be able to do by hand”

Example: Fixed-pH Reaction Goal: maintain given pH throughout reaction For in-vitro modeling of natural environment Method: periodically test, adjust pH if needed Fluid sample = input (0); Fluid acid = input(1); Fluid base = input(2); do { Fluid pH_test = mix(sample, 0.9, indicator, 0.1); // test pH of sample double pH = test_luminescence(pH_test); if (pH > 7.5) { // if pH too high, add acid sample = mix (sample, 0.9, acid, 0.1); } else if (pH < 6.5) { // if pH too low, add base sample = mix (sample, 0.9, base, 0.1); } wait(60); } while (detect_activity(sample)); Feedback-Intensive Applications: Recursive descent search Directed evolution Cell isolation and manipulation Dose/response curves Long, complex protocols

Real Experiments in Progress How do mammalian signal transduction pathways respond to complex inputs? With Jeremy Gunawardena (Harvard Medical School) Isolate cells and stimulate with square wave, sine wave, etc. What are the best indicators for oocyte viability? With Mark Johnson (Colorado Center for Reproductive Medicine) During in-vitro fertilization, monitor cell metabolites and select healthiest embryo for implantation New part of first – mention cell traps New part of second – mention sensing

Algorithms for Efficient Mixing Mixing is fundamental operation of microfluidics Prepare samples for analysis Dilute concentrated substances Control reagant volumes How to synthesize complex mixture using simple steps? Many systems support only 50/50 mixers Should minimize number of mixes, reagent usage Note: some mixtures only reachable within error tolerance  N Analogous to ALU operations on microprocessors Note: important to mix on-chip Otherwise reagants leave system whenever mix needed Enables large, self-directing experiments Interesting scheduling and optimization problem

Why Not Binary Search? 3/8 1 1/2 1/4 1/2 3/8 5 inputs, 4 mixes

Why Not Binary Search? 3/8 1 1/2 3/4 3/8 4 inputs, 3 mixes 1/2 1/4 1/2 3/8 1 1/2 3/4 3/8 4 inputs, 3 mixes 1/2 1/4 1/2 3/8 5 inputs, 4 mixes

Min-Mix Algorithm Simple algorithm yields minimal number of mixes For any number of reagents, to any reachable concentration Also minimizes reagent usage on certain chips

Min-Mix Algorithm: Key Insights The mixing process can be represented by a tree. A B B A 5/8 A, 3/8 B

Min-Mix Algorithm: Key Insights The mixing process can be represented by a tree. The contribution of an input sample to the overall mixture is 2-d, where d is the depth of the sample in the tree d 2-d A 3 1/8 B 2 1/4 B 1 1/2 A 5/8 A, 3/8 B

Min-Mix Algorithm: Key Insights The mixing process can be represented by a tree. The contribution of an input sample to the overall mixture is 2-d, where d is the depth of the sample in the tree In the optimal mixing tree, a reagent appears at depths corresponding to the binary representation of its overall concentration. d 2-d A 3 1/8 5 = 101 1 3 = 011 1 B 2 1/4 B 1 1/2 A 5/8 A, 3/8 B

Min-Mix Algorithm Example: mix 5/16 A, 7/16 B, 4/16 C In paper: pseudocode, proof of correctness / optimality 4 3 2 1 1/16 1/8 1/4 1/2 d 2-d A B A B B B A B C A B C A=5 B=7 C=4 =0101 =0111 =0100

CAD Tools for Microfluidic Chips Microfluidic design tools are in their infancy Most groups use Adobe Illustrator or AutoCAD Limited automation; every line drawn by hand Microfluidic CAD is different than Electronic CAD Control ports are most expensive commodity Cannot cascade control signals without adding new layer Curved channels needed Extra dimensions: channel width, channel height Non-local effects: hot/cold, light/dark, etc. Should adjust flow channels + layout to minimize control (cannot use grid) Must tolerate alignment errors in assembling layers Interesting research questions in microfluidics CAD

Work in Progress: Automatic Routing First target: automate the routing of control channels Connecting valves to pneumatic ports is very tedious Simple constraints govern the channel placement AutoCAD plugin automates this task (by Nada Amin)

Related Work Automatic generation / scheduling of biology protocols Robot scientist: generates/tests genetic hypotheses [King et al.] EDNAC computer for automatically solving 3-SAT [Johnson] Compile SAT to microfluidic chips [Landweber et al.] [van Noort] Mapping sequence graphs to grid-based chips [Su/Chakrabarty] Custom microfluidic chips for biological computation DNA computing [Grover & Mathies] [van Noort et al.] [McCaskill] [Livstone, Weiss, & Landweber] [Gehani & Reif] [Farfel & Stefanovic] Self-assembly [Somei, Kaneda, Fujii, & Murata] [Whitesides et al.] General-purpose microfluidic chips Using electrowetting, with flexible mixing [Fair et al.] Using dialectrophoresis, with retargettable GUI [Gascoyne et al.] Using Braille displays as programmable actuators [Gu et al.] First category sits above our system Second category sits below our system Third category, we’re not necessarily competing – trying to build common layer that can target any

Conclusions http://cag.csail.mit.edu/biostream Abstraction layers for programmable microfluidics Fluidic ISA BioStream language Vision for microfluidics: everyone uses standard chip Thousands of storage cells Dozens of parallel mixers Integrated support for cell manipulation, PCR, readout, etc. Vision for software: a defacto language for experimental science You can download a colleague’s code, run it on your chip Say at end: we have end-to-end system working http://cag.csail.mit.edu/biostream