Skip to content

Commit 97a50f8

Browse files
authored
Merge pull request #124 from OpenTrons/update-docs-getting-started-page
Update docs getting started page
2 parents 1eb2d22 + 93b8ee8 commit 97a50f8

File tree

6 files changed

+173
-116
lines changed

6 files changed

+173
-116
lines changed

docs/source/api.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ Robot
1313
All protocols are set up, simulated and executed using a Robot class.
1414

1515
.. autoclass:: Robot
16-
:members: connect, home, reset, run, simulate, commands, move_to, containers, actions, disconnect, pause, resume, stop, diagnostics, get_warnings, add_instrument, get_mosfet, get_motor
16+
:members: connect, home, reset, run, simulate, commands, move_to, containers, actions, disconnect, head_speed, pause, resume, stop, diagnostics, get_warnings, add_instrument, get_mosfet, get_motor
1717

1818
Pipette
1919
-----------------

docs/source/getting_started.rst

Lines changed: 121 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ Now that you've installed Opentrons API on your computer, you have access to a v
5454
trash_container=trash,
5555
tip_racks=[tiprack],
5656
min_volume=20,
57-
max_volume=2000,
57+
max_volume=200,
5858
axis="a",
5959
channels=1
6060
)
@@ -78,46 +78,29 @@ Now that you have a robot to run commands on, you need to tell it what container
7878
Containers
7979
^^^^^^^^^^
8080

81-
For each container you want to use on the deck, you need to load it into your file by telling the robot what it is, where it is, and what to label it. The label you give the container is what will appear in the app when you start calibrating.
82-
8381
.. code-block:: python
82+
83+
plate = containers.load('96-flat', 'B2', 'optional-unique-name')
8484
85-
mycontainer = containers.load(
86-
'container type',
87-
'slot position'
88-
'given name'
89-
)
85+
Each container on the deck is loaded using the container's name and assign it to a slot. The API comes packaged with a set of containers, and users can create and add their own custom containers.
9086

9187
**containers.load** (*container, slot, name*)
9288

9389
* **container -** type of container (aka "trough-12row")
9490
* **slot -** the slot location on the deck ("A1" through "E3")
95-
* **name -** custom name, used inside API when saving calibration data
91+
* **name -** (optional) custom name, used inside API when saving calibration data
9692

97-
The example below declares 3 different containers and assigns them to the appropriate slots on the deck.
93+
The robot will save calibrated container coordinates from old runs based on the ``container`` and ``slot`` combination. Therefore, if you repeatedly place the same container type in the same slot, the robot will assume your old calibrated coordinates for that container.
9894

99-
.. testcode:: main
100-
101-
tiprack = containers.load(
102-
'tiprack-200ul',
103-
'A1',
104-
'tiprack'
105-
)
95+
However, if you include the optional third argument ``name``, the robot will assume coordinates based off the ``name`` and ``slot`` combination. This allows a container to differentiate it's saved coordinates from previous protocols.
10696

107-
plate = containers.load(
108-
'96-PCR-flat',
109-
'B2',
110-
'plate'
111-
)
112-
113-
trash = containers.load(
114-
'point',
115-
'C3',
116-
'trash'
117-
)
97+
The example below declares 3 different containers and assigns them to the appropriate slots on the deck. The trash uses a custom name, so that it doesn not inherit the coordinates of previous "point" containers at slot "C3".
11898

119-
120-
The robot will save calibration data from old runs based on the container type, slot position and given name. Thus, if you always give something the same arguments, it will populate the app with old calibration data. If you do not want it to do this, simply change the given name to unique names.
99+
.. testcode:: main
100+
101+
tiprack = containers.load('tiprack-200ul', 'A1')
102+
plate = containers.load('96-PCR-flat', 'B2')
103+
trash = containers.load('point', 'C3', 'my-weird-trash-container')
121104

122105

123106
Pipettes
@@ -126,39 +109,45 @@ Pipettes
126109
.. code-block:: python
127110
128111
mypipette = instruments.Pipette(
129-
name="mypipette",
130-
axis="b",
112+
axis="b",
131113
max_volume=200,
132-
min_volume=20,
133-
trash_container=trash,
134-
tip_racks=[tiprack],
135-
channels=1
114+
min_volume=20,
115+
tip_racks=[tiprack],
116+
trash_container=trash,
117+
channels=1,
118+
name="mypipette"
136119
)
137120
138121
**instruments.Pipette** (*name, trash_container, tip_racks, min_volume, max_volume, axis, channels*)
139122

140-
* **name -** name you give pipette
141123
* **axis -** axis the pipette is on (a or b)
142124
* **max_volume -** maximum volume of pipette
143-
* **min_volume -** minimum volume of pipette
144-
* **trash_container -** given name of container where you want to deposit tips
145-
* **tip_racks -** array (list) of container(s) where you want to pick up tips
146-
* **channels -** number of channels (1 or 8)
125+
* **min_volume -** (optional) minimum volume of pipette
126+
* **tip_racks -** (optional) array (list) of container(s) where you want to pick up tips
127+
* **trash_container -** (optional) given name of container where you want to deposit tips
128+
* **channels -** (optional) number of channels (1 or 8)
129+
* **name -** (optional) name you give pipette
147130

148-
This example loads a single channel, 20-200 uL pipette on the ``b`` axis that pulls tips from tiprack and deposits them in trash
149-
150-
.. testcode:: main
131+
To use the tip-tracking features, create your pipette with tip racks and a trash container like the following example:
151132

152-
pipette = instruments.Pipette(
153-
name="p200",
154-
trash_container=trash,
155-
tip_racks=[tiprack],
156-
min_volume=20,
133+
.. code-block:: python
134+
135+
mypipette = instruments.Pipette(
136+
axis="b",
157137
max_volume=200,
158-
axis="b",
159-
channels=1
138+
tip_racks=[tiprack],
139+
trash_container=trash
160140
)
161141
142+
mypipette.pick_up_tip() # picks up tip at A1
143+
mypipette.drop_tip() # drops tip in the trash container
144+
mypipette.pick_up_tip() # picks up tip at B1
145+
mypipette.return_tip() # drops tip back at B1
146+
147+
.. testcode:: main
148+
149+
150+
162151
Commands
163152
-----------------------------
164153

@@ -172,33 +161,48 @@ Before you can start moving liquid around, you need to pick up a tip! You can p
172161

173162
**pipette.pick_up_tip** (*location*)
174163

175-
* **location -** container[position] location to pick up tip
164+
* **location -** container[position] the tip's current position
176165

177166
.. testcode:: main
178167

179168
p200.pick_up_tip(tiprack['A2'])
180169

181-
However, if you just want to go through the tips in a tip rack in order, there is no need to call a location. The example below will pick up the first available tip, and the API will keep track of which tips have been used so far in the protocol.
182-
183-
.. testcode:: main
184-
185-
p200.pick_up_tip()
186-
187170
In addition to picking up a tip, there is a command to drop tip.
188171

189172
**pipette.drop_tip** (*location*)
190173

191-
* **location -** container[position] location to drop tip
174+
* **location -** container[position] the position to drop the tip
192175

193176
.. testcode:: main
194177

195178
p200.drop_tip(tiprack['A2'])
196179

197-
While you can only pick up tips from tip racks, you can eject tips back into the tiprack, or send them to the trash. While you can specify trash as a location, you can also use the default version of drop tip like the example below.
180+
The behavior or tip commands changes depending on whether you have attached tip racks and/or trash containers to your pipette.
181+
This happens when a pipette is created through using it's ``tip_racks`` and ``trash`` properties.
198182

199-
.. testcode:: main
183+
.. code-block:: python
200184
201-
p200.drop_tip()
185+
p200 = instruments.Pipette(
186+
axis='a',
187+
max_volume=200,
188+
tip_racks=[tiprack],
189+
trash=trash)
190+
191+
With a list of one or more tip racks, a pipette can automatically iterate through it's tips without passing any arguments, and automatically drop tips in the trash.
192+
193+
.. code-block:: python
194+
195+
p200.pick_up_tip() # automatically goes to tiprack['A1']
196+
p200.drop_tip() # automatically goes to trash
197+
198+
**pipette.return_tip** ()
199+
200+
With one or more tip racks attached, a pipette can also return a tip to it's original position
201+
202+
.. code-block:: python
203+
204+
p200.pick_up_tip() # automatically goes to tiprack['A1']
205+
p200.return_tip() # automatically goes back to tiprack['A1']
202206
203207
204208
Aspirate
@@ -212,13 +216,26 @@ Aspirate
212216
.. testcode:: main
213217

214218
p200.aspirate(200, plate['A1'])
219+
p200.dispense()
215220

216221
You can link multiple aspirates together in order to pick up liquid from multiple locations
217222

218223
.. testcode:: main
219224

220225
p200.aspirate(50, plate['A1']).aspirate(100, plate['B1'])
221226

227+
If no volume is passed, the pipette will automatically aspirate to it's ``max_volume``
228+
229+
.. testcode:: main
230+
231+
p200.aspirate(plate['A1']) # 200ul
232+
233+
In addition, if no location is passed, the pipette will aspirate from it's current position
234+
235+
.. testcode:: main
236+
237+
p200.aspirate() # 200ul from this position
238+
222239

223240
Dispense
224241
^^^^^^^^
@@ -238,7 +255,6 @@ If you want to deposit all of the liquid you just aspirated, there is no need to
238255

239256
.. testcode:: main
240257

241-
p200.aspirate(200, plate['A1'])
242258
p200.dispense(plate['B1'])
243259

244260

@@ -257,11 +273,17 @@ While you can call multiple aspirate and dispense commands to the same location,
257273

258274
p200.mix(3, 100, plate['A1'])
259275

276+
Call ``mix()`` without a location, and the pipette will mix at the previously referenced well
277+
278+
.. testcode:: main
279+
280+
p200.dispense(plate['B2']).mix(3, 100)
281+
260282

261283
Chaining Commands
262284
^^^^^^^^^^^^^^^^^
263285

264-
Now that you know the basic commands, you can start transferring liquids! However, your code can get lengthy quickly is you write it like this.
286+
Now that you know the basic commands, you can start transferring liquids! However, your code can get lengthy quickly if you write it like this.
265287

266288
.. testcode:: main
267289

@@ -277,12 +299,7 @@ Instead of giving each command it's own line, you can chain them together using
277299
.. testcode:: main
278300

279301
p200.pick_up_tip().aspirate(200, plate['A1']).dispense(plate['B1'])
280-
281-
282-
Command Attributes
283-
-----------------------------
284-
285-
In addition to commands, you can attach attributes to your movements.
302+
286303

287304
Touch Tip
288305
^^^^^^^^^
@@ -311,7 +328,7 @@ You can blow out liquid immediately after a dispense command in the same locatio
311328

312329
.. note::
313330

314-
If the trash container is given a "point" labware name, instead of another container (like "trough-12row"), there is no need to call a position within the container.
331+
Since the trash container is given a "point" labware name, it has no wells inside it. Therefore there is no need to call a position within the container.
315332

316333
Delay
317334
^^^^^
@@ -324,26 +341,29 @@ Delay commands can be called between any movement commands, so you have complete
324341

325342
.. testcode:: main
326343

327-
p200.delay(10).aspirate(100, plate['A1'])
344+
p200.aspirate(120, plate['A1']).delay(1).dispense(10)
345+
p200.dispense(plate['B2']).delay(60)
346+
p200.aspirate(100, plate['B2'])
328347

329-
Dispensing Positions
330-
^^^^^^^^^^^^^^^^^^^^
348+
Position Within a Well
349+
^^^^^^^^^^^^^^^^^^^^^^
331350

332-
Want to deposit at the top of a tube? Pull liquid from the bottom of the well? Mix from the middle? Easy.
351+
Want to deposit at the top of a tube? Pull liquid from the bottom of the well? It's easy with a Well's ``top()`` and ``bottom()`` methods.
333352

334353
**container.top** (*distance*)
335354

336-
**container.bottom** (*distance*)
355+
* **distance -** (optional) distance above/below top of Well (mm)
337356

338-
* **distance -** distance from calibration position (mm)
357+
**container.bottom** (*distance*)
339358

340-
Containers are calibrated to the bottom of the well, and each labware definition has an inherent depth, which provides the calculated top position. You can specify each of these locations anytime you use a container[position], as well as adjust them up (+) or down (-) by adding a distance.
359+
* **distance -** (optional) distance above bottom of Well (mm)
341360

342361
.. testcode:: main
343362

344-
p200.dispense(plate['A1'].top()) # at the top of well
345-
p200.mix(3, 100, plate['B2'].bottom(5)) # 5mm above bottom of well
346-
p200.dispense(plate['A1'].top(-3)) # 3mm below top of well
363+
well = plate['A1']
364+
p200.dispense(well.top()) # at the top of well
365+
p200.mix(3, 100, well.bottom(5)) # 5mm above bottom of well
366+
p200.aspirate(well.top(-3)) # 3mm below top of well
347367

348368
Homing
349369
------
@@ -355,7 +375,7 @@ You can instruct the robot to home at any point in the protocol, or just home on
355375
* **axes -** the axes you want to home
356376
* **enqueue -** True or False
357377

358-
When the python file is loaded into the protocol, it runs through all of the commands. When enqueue=False (default), this will cause the robot to home immediately upon loading the protocol, whereas if enqueue=True, it will run when it is called in the protocol.
378+
Normally, home commands are run immediately when called, and therefore should not be included in a protocol. However, if you need to home during a protocol run, include the argument ``enqueue=True``.
359379

360380
.. testcode:: main
361381

@@ -364,6 +384,25 @@ When the python file is loaded into the protocol, it runs through all of the com
364384
robot.home('ab', enqueue=True) # adds "home ab" command to protocol queue
365385
robot.home('xyz', enqueue=True) # adds "home xyz" command to protocol queue
366386

387+
Head Speed
388+
----------
389+
390+
The speed of the robot's X and Y movements can be sped up or slowed down.
391+
392+
**robot.head_speed** (*rate*)
393+
394+
* **rate -** the speed at which the X and Y axis will move (millimeters per minute)
395+
396+
This method will immediately set the speed of the robot, and all following movements will use that speed.
397+
398+
.. note::
399+
Speeds too fast (around 6000 and higher) will cause the robot to skip step, be careful when using this method
400+
401+
.. testcode:: main
402+
403+
robot.head_speed(4500)
404+
p200.pick_up_tip()
405+
367406
Move To
368407
-------
369408

0 commit comments

Comments
 (0)