controlling a robotic marine environmental sampler with the ruby scripting language

7
http://jla.sagepub.com/ Automation Journal of the Association for Laboratory http://jla.sagepub.com/content/12/1/56 The online version of this article can be found at: DOI: 10.1016/j.jala.2006.07.013 2007 12: 56 Journal of Laboratory Automation Jones and Kevin Wheeler Brent Roman, Chris Scholin, Scott Jensen, Eugene Massion, Roman Marin III, Christina Preston, Dianne Greenfield, William Controlling a Robotic Marine Environmental Sampler with the Ruby Scripting Language Published by: http://www.sagepublications.com On behalf of: Society for Laboratory Automation and Screening can be found at: Journal of the Association for Laboratory Automation Additional services and information for http://jla.sagepub.com/cgi/alerts Email Alerts: http://jla.sagepub.com/subscriptions Subscriptions: http://www.sagepub.com/journalsReprints.nav Reprints: http://www.sagepub.com/journalsPermissions.nav Permissions: What is This? - Feb 1, 2007 Version of Record >> by guest on October 11, 2013 jla.sagepub.com Downloaded from by guest on October 11, 2013 jla.sagepub.com Downloaded from by guest on October 11, 2013 jla.sagepub.com Downloaded from by guest on October 11, 2013 jla.sagepub.com Downloaded from by guest on October 11, 2013 jla.sagepub.com Downloaded from by guest on October 11, 2013 jla.sagepub.com Downloaded from by guest on October 11, 2013 jla.sagepub.com Downloaded from

Upload: independent

Post on 24-Apr-2023

0 views

Category:

Documents


0 download

TRANSCRIPT

http://jla.sagepub.com/Automation

Journal of the Association for Laboratory

http://jla.sagepub.com/content/12/1/56The online version of this article can be found at:

 DOI: 10.1016/j.jala.2006.07.013

2007 12: 56Journal of Laboratory AutomationJones and Kevin Wheeler

Brent Roman, Chris Scholin, Scott Jensen, Eugene Massion, Roman Marin III, Christina Preston, Dianne Greenfield, WilliamControlling a Robotic Marine Environmental Sampler with the Ruby Scripting Language

  

Published by:

http://www.sagepublications.com

On behalf of: 

  Society for Laboratory Automation and Screening

can be found at:Journal of the Association for Laboratory Automation Additional services and information for    

  http://jla.sagepub.com/cgi/alertsEmail Alerts:

 

http://jla.sagepub.com/subscriptionsSubscriptions:  

http://www.sagepub.com/journalsReprints.navReprints:  

http://www.sagepub.com/journalsPermissions.navPermissions:  

What is This? 

- Feb 1, 2007Version of Record >>

by guest on October 11, 2013jla.sagepub.comDownloaded from by guest on October 11, 2013jla.sagepub.comDownloaded from by guest on October 11, 2013jla.sagepub.comDownloaded from by guest on October 11, 2013jla.sagepub.comDownloaded from by guest on October 11, 2013jla.sagepub.comDownloaded from by guest on October 11, 2013jla.sagepub.comDownloaded from by guest on October 11, 2013jla.sagepub.comDownloaded from

Keywords:

scripting,

Linux,

autonomous

sampler,

ELIZA,

Ruby,

molecular pr

open-source,

object-orient

Feature Story

56 JAL

Controlling a Robotic MarineEnvironmental Sampler withthe Ruby Scripting Language

Brent Roman,* Chris Scholin, Scott Jensen, Eugene Massion, Roman Marin III,Christina Preston, Dianne Greenfield, William Jones, and Kevin Wheeler

Monterey Bay Aquarium Research Institute, Moss Landing, CA

obes,

ed

A F

The Environmental Sample Processor (ESP) is an

autonomous robotic instrument developed at the

Monterey Bay Research Aquarium Institute (MBARI) that

operates below the ocean’s surface, sampling raw

seawater and executing a variety of sample manipulation

and analytical protocols, in situ. It uses DNA and antibody

probes to identify marine planktonic organisms and

substances they produce. Initial prototypes of the ESP

were hosted on an Intel i486 CPU running a commercial

real-time operating system (OS). The application, coded

in Cþþ, included a custom ’macro’ language interpreter

to direct biochemical analyses. To achieve greater

flexibility and minimize the development effort for the

2nd generation of the ESP (2G ESP), MBARI replaced its

’macro’ language with a general purpose, open-source

scripting language, selecting Ruby for its unique

combination of a succinct, English-like syntax with

a seamless underlying object-oriented paradigm. The 2G

ESP application, aside from custom servo control

firmware, is coded entirely in Ruby, hosted on a low-

power ARM9 CPU running Linux. Servo control was

distributed onto a network of dedicated microcontrollers

to cope with the nondeterministic delays inherent in the

Linux operating system and Ruby interpreter. ( JALA

2007;12:56–61)

*Correspondence: Brent Roman, B.S., Monterey Bay AquariumResearch Institute, 7700 Sandholdt Road, Moss Landing, CA95039, USA; Phone: þ1.831.775.1808; E-mail: [email protected]

1535-5535/$32.00

Copyright �c 2007 by The Association for Laboratory Automation

doi:10.1016/j.jala.2006.07.013

ebruary 2007

INTRODUCTION

Many of the diagnostic protocols for detectingmolecular signatures share an overlapping set ofrequirements such as collecting, concentrating,preserving, and disrupting cells. They apply a seriesof reagents in a timed sequence and extract particu-lates from the sample. By developing a low power,compact instrument that meets this core set of func-tional requirements, it would be possible to conductmany commonly applied molecular biological analy-ses remotely, in situ.

Toward that goal, a group of scientists and engi-neers at the Monterey Bay Aquarium Research Insti-tute (MBARI) undertook development of theEnvironmental Sample Processor (ESP)1,2,a (Scholinet al. 2005). The ESP is a robotic instrument that col-lects raw water samples, concentrates particulates,and applies molecular probes to identify microorgan-isms based on signature ribosomal ribonucleic acid(rRNA) sequences. In addition, MBARI has recentlydeveloped an antibody-based test for the detection ofthe algal neurotoxin, domoic acid, thus enabling theESP to detect both specific species and the toxins theyproduce. It also archives particulates in discretesamples, allowing a variety of nucleic acid analyses,microscopy, and other types of laboratory proce-dures to be used after the instrument is recovered.To date, the ESP team has focused on detectinga suite of marine planktonic organisms. Prototypesof the ESP have been deployed in Monterey Bayand the Gulf of Maine at depths of 3e15 m.4,5

ahttp://www.mbari.org/news/homepage/2006/esp-II.htmlhttp://www.mbari.org/microbial/ESP

Feature Story

The ESP consists of eight major robotic components:a carousel, manipulator arm, two clamps, three syringepumps, and a CCD camera (Figs. 1 and 2). The carouselstores up to 150 puck-shaped reaction chambers, which ac-commodate a wide variety of 25 or 13 mm diameter filtersor chemically adsorptive media. An elevator and rotary ma-nipulator arm, with a two fingered gripper, moves pucksfrom the carousel to sample collection or processing stationswhere they are sealed in clamps, providing connections to thesample port and/or reagent valve manifolds. Each clampcontains an embedded heater pad to regulate the temperatureof liquid in the puck from ambient (4e30 �C) to w100 �C.The elevator pushes pucks up to an imaging station where

Figure 1. Annotated solid model of the 2nd generation ESPmechanism with electrical and most fluidic components omittedfor clarity. Overall dimensions are approximately 41 cm in diame-ter by 76 cm high.

a CCD camera records the luminescence pattern of com-pleted probe array assays. The instrument is usually deployedat a fixed depth on a subsurface mooring with an electrome-chanical cable attached to a surface float containing a radiomodem and antenna.

The ESP uses custom DNA probe arrays for rRNA se-quences that are indicative of specific species or groups ofspecies (e.g., Fig. 3). Sample collection begins by loadinga puck into the collection clamp containing a filter membranewith pores smaller than the organisms being sought. A sy-ringe pump then draws raw water through this filter until itis saturated with particulates. To develop a probe array,the ESP breaks down cell membranes, homogenizing a sam-ple using a chaotrope and heat. The resulting filtered samplehomogenate is retained. The sample collection puck is re-placed with an array puck and the homogenate is applied,followed by a sequence of reagents that reveal rRNA mole-cules bound at specific locations on the array grid using sand-wich hybridization3,5e8. The radio modem then transmits animage of the resulting array to a remote location for interpre-tation. Different arrays are tailored to specific groups of

Figure 2. 2nd generation ESP being readied for its initial deploy-ment in the Monterey Bay viewed from roughly the same point asthe solid model rendering depicted in Figure 1.

JALA February 2007 57

Feature Story

Figure 3. Detection of invertebrate larvae, pennate diatoms, and groups of bacteria on a single ESP probe array.

organisms such as bacterioplankton, harmful algae, plank-tonic microbes, harmful algae, or invertebrate larvae.

Users controlled early prototypes of the ESP via a custom‘‘macro’’ language that rigorously defined the sequence ofsteps to be performed by the instrument. This languagelacked any provision for looping, conditionals, or parameterpassing, resulting in scripts that were inflexible, needlesslylong, very repetitive and, consequently, difficult to maintain.Supervisory system logic and lower level control were hardcoded in Cþþ. Even trivial bug fixes or enhancements neces-sitated a recompilation of the application binary, requiringsoftware engineering expertise beyond that of typical endusers.

THE 2ND GENERATION

In early 2003, MBARI was awarded a grant from the Na-tional Science Foundation to make the ESP technology moreaccessible to outside research groups by developing a modu-lar instrument that could be easily reconfigured to suit a widevariety of deployment and analysis scenarios. The designteam soon recognized that significant improvements in theESPs flexibility and ease of use could not be achieved withouta major overhaul of its scripting capabilities. It gradually be-came clear that extending the existing interpreter would con-sume more development time than adapting an establishedopen-source scripting language, or, if possible, adoptingone unchanged. As the search for a suitable language pro-gressed, the design team realized that the need to recompilethe application for enhancements and bug fixes would dimin-ish to the extent that the object-oriented Cþþ applicationlogic was rewritten in the scripting language. This rewritewould likely be more straightforward if the chosen scriptinglanguage was also object-oriented. Furthermore, if the

58 JALA February 2007

language interpreter could conveniently process commandsentered interactively, it could also function as the instru-ment’s ‘‘command shell’’, replacing the maze of hard codedmenus that characterized the existing software’s userinterface.

The above requirements quickly winnowed the pack ofpopular, open-source scripting languages. TCL, PHP and,to a lesser extent, Perl, were not sufficiently object-oriented.Javascript (or, more precisely, ECMAScript) implementa-tions were usually tied too intimately to a web browser andlacked standardized input/output support. Python was con-sidered, but ultimately rejected due to its rigid whitespaceand punctuation requirements, which, while improving pro-gram structure and readability, tend to make the languagecumbersome for interactive use. Ruby seemed to meet allthe requirements. Ultimately, it was determined that Pythonwould be a fall back if Ruby did not prove viable.

MBARIs design team chose Linux as the ESP host CPUsoperating system because Python and Ruby were alreadyported to Linux and many vendors of low-power (AdvancedRisk Machine, Ltd., ARM) CPUs boards offered Linux ker-nels configured for their hardware. Further, the free avail-ability of Linux source code reduced the fear that someobscure device driver or kernel bug might significantly delaythe project. However, Linux is not a replacement for a real-time operating system. The current crop of small, low-powerCPUs running Linux cannot reliably process real-time servomotor control loops sampling at the 30e80 Hz required forthe ESPs actuators. Even if the application level latencies in-herent in Ruby’s garbage collector could be eliminated, theLinux operating system running on the ESPs host CPUwould still occasionally delay processing external interruptevents for over 20 ms while compact flash disk accesses wereperformed. Such long interrupt latencies dictate that the

Feature Story

Linux host offload servo control onto dedicated peripheralhardware, regardless of how efficiently the application isimplemented.

The 2nd generation ESPs design therefore includes sixmicrocontrollers that relieve the host processor of any re-sponsibility for real-time response. These microcontrollerscommunicate with the host and each other via a shared serialbus.b They are programmed in ANSI-’C’ (with some vendor-specific extensions) and store their code in nonvolatile flashmemory. Their firmware cannot be easily modified in thefield, so it must be highly configurable and implement onlythe most primitive operations. A unique address, set manu-ally by switches, identifies each otherwise identical microcon-troller on the bus. The host configures all microcontrollers atapplication startup for their specific roles according to theirbus addresses.

WHERE RUBY SHINES

The single language feature that has proven most useful indevelopment of the ESP is Ruby’s open classes. Ruby classesare ‘‘open’’ in the sense that they may be changed after ob-jects are instantiated.c One may even add, delete, or altermethods in base classes such as String, Float, and Integer.Objects in languages, like Java, Cþþ, and Pythond, whoseclasses are ‘‘closed’’, may not be instantiated until their classdefinition is completely parsed. Once the class is thus defined,it cannot be changed. Typically, one cannot alter the behav-ior base classes in these languages at all and even one’s ownclasses cannot be changed once loaded.

The ESP realizes very practical benefits from Ruby’s openclasses. For instance, imagine that a team of molecular biol-ogists, after spending hours working on a new biochemicalprotocol, discover that previously loaded code needs to be al-tered or enhanced before work can continue. A languagewith closed classes would require that the application beexited and restarted with the modified code to effect thischange, losing much of the ESPs critical state in the process.However, Ruby’s combination of open classes and dynamiccompilation allows modified methods to be reloaded ‘‘onthe fly’’, as the application continues operating, uninter-rupted, thus preserving the instrument’s state.

There is justifiable controversy surrounding open classesbecause they are easily misused. Changing the behavior ofexisting methods in base classes is especially dangerous, as li-braries and other applications typically depend on them.Base classes modified to support a specific application mayalso break libraries that one might try to use in the future.Therefore, programmers should adopt the convention that

bPhilips Semiconductors Inter-Integrated Circuit (I2C) bus.cRuby borrows heavily from Xerox PARC’s Smalltalk-80 language in thisregard.dRedefining an existing Python class is allowed, however it creates a distinctnew class of the same name. The behavior of existing objects is not changed.Python calls modification of the attributes of existing classes‘‘monkeypatching’’, which uses of a different syntax than class definition.

base class modifications be restricted to adding methodsonly, never deleting or altering them, despite the fact thatRuby allows this.

An unusual feature of Ruby’s method inheritance is that itlets one optionally associate methods with a particular objectinstance rather than its class. The ESP uses such ’singletonmethods’ to good effect in a number of situations. For exam-ple, although there are a number of Clamp objects, the col-lection clamp is unique in that closing it also causes theESP to prepare to collect a raw water sample. The RubyESP application realizes this by overriding the close instancemethod of the collection clamp, whereas Java or Cþþ woulddemand the creation of an extra singleton class.

Ruby’s syntax is remarkably relaxed and free of punctua-tion. An arbitrary number of whitespace characters may beinserted anywhere to separate language tokens and thereare no line indentation rules. If it would be syntacticly com-plete, starting a new line terminates the current expression;otherwise, the next line is appended to it. This parsing ruleneatly eliminates the trailing semicolons that riddle code inlanguages whose syntax is derived from ’C’e, while still allow-ing for multiline expressions without explicit line continua-tion characters. Parentheses in Ruby are needed only toalter the default operator precedence. They do not delimitboolean expressions in control structures as they do in ’C’and its derivatives. Parentheses may even be omitted aroundmethod argument lists for simple calls, thus giving them theappearance of ‘‘commands’’ rather than function invoca-tions. Of course, Ruby’s free form syntax can be abused towrite code that is difficult to read: a programmer intent onwriting obscure code will find a way to do so in any language.

The ESP exploits Ruby’s succinct, English-like syntax tomake a useful subset of the language readily accessible toits intended end users. They are typically microbiologistsand not expert computer programmers. Most high-levelESP commands are implemented as method calls on prede-fined Ruby objects so that end users may code protocolswithout understanding much about object-oriented program-ming. Here are some basic examples:

# Lower the puck elevator in the carousel

Elevator down

# Rotate the carousel so the elevator will

# lift pucks in tube #3

Carousel.to 3

CC. close #Close the collection clamp

The ESP associates names with these predefined globalconstant objects by defining a singleton method for each thatsimply returns the object’s canonical name. While this maysound trivial, it is an aspect of introspection missing frommost object-oriented systems. This ability to derive any ob-ject’s name from a reference to it (e.g., the string ‘‘Elevator’’,given only a reference to the Elevator object) lets ESP log file

eThese include Cþþ, PHP, Java, and JavaScript.

JALA February 2007 59

Feature Story

entries take the form of valid commands that may be reen-tered into the system verbatim if it is desired to repeat themlater.

RUBY’S DARKER FACETS

Like all programming languages, Ruby has a few warts anddark corners. The fact that Ruby assigns variables no staticdata types allows it to forgo their declaration entirely. How-ever, traditional variable declarations do more than deter-mine the data type of variable (or object) identifiers. Theyalso indicate their scope and access restrictions. Ruby resortsto prefixing all variable references with punctuation charac-ters to indicate their scope (e.g., local, @object, @@class,or $global) and assumes that any identifier beginning witha capital letter that is the target of an assignment is a con-stant.f Although these conventions trip up new program-mers, they are quickly mastered.

A more insidious problem with Ruby is that a context-freegrammar cannot determine whether an unprefixed identifierrefers to a local variable or a method name. Ruby resolvesthis ‘‘Variable/Method’’ ambiguity as each method is parsedby treating each new identifier encountered as a methodname until it appears in the method’s argument list or onthe left side of an assignment. Thereafter, the new identifieris treated as a reference to a local variable.9 This can leadto unexpected behavior when methods contain control struc-tures that do not execute in the same (top-down) order inwhich code is parsed. Consider the following (admittedlycontrived) example:

def foo

# parameterless method that

# always returns the string bar

‘bar’

end

2.times do

# here, foo is a method call

# because it has not yet been assigned

print ‘‘foo¼’’, foo, ‘‘\n’’

# foo becomes a local variable as a

# side effect of the following assignment

foo¼ ‘confused?’

print foo, ‘‘\n’’

end

This script outputs the text:

foo¼ bar

confused?

foo¼ bar

confused?

fAll constants in Ruby have global visibility, but they exist in the namespaceof the module in which they were defined.

60 JALA February 2007

To resolve this Variable/Method ambiguity, one can ex-plicitly force Ruby’s parser to interpret an identifier asa method call by prefixing it with ’self.’, as in ’self.foo’. Toforce the parser to interpret an identifier as a variable, simplyassign it some value before any other reference to it appearsin the text of the method. Neither technique is particularlypretty, but they do the job. A better approach, in practice,is to try to avoid this ambiguity entirely by taking care to en-sure that no local variable shares the same name as any of theobject’s methods.

UNIT TESTING AND SIMULATION

Dynamically typed scripting languages provide very little in-formation to drive static error analysis. Mistakes that wouldillicit trivial compiler errors in strongly typed languages, suchas misspelled method or variable names, will go undetecteduntil the offending methods execute. Programmers workingin scripting languages typically make up for their lack ofcompile-time checking by writing extensive unit tests to exer-cise their code. Effective unit tests can uncover subtle logicerrors in a syntactically correct program.g However, writingthem is an art by itself.

The ESPs target users are not required to be experiencedprogrammers, well versed in the art of unit testing. Never-theless, the protocol control scripts they typically write, al-though quite simple logically, run for many hours and mayconsume irreplaceable samples and expensive reagents. Dis-covering a typo halfway through such a protocol’s executionwould be very frustrating. So, building a simulation capabil-ity into the ESP software was recognized as a requirementearly in its design.

The ESPs simulator models the serial bus, its microcon-trollers, and, in a very primitive way, the physical hardwareto which they are normally connected. It redirects the bytestream that would normally flow between the host and theexternal microcontrollers to internal Ruby proxy objects thatmodel them. Many physical constraints that would cause er-rors in the real hardware are not detected during simulation.However, the models are currently good enough to detecttypos and most commonly occurring logic errors such ascommanding a physical actuator to an undefined positionor trying to heat a puck to an unattainable temperature.Planned enhancements to the ESP simulator include theability to estimate the amount of time, power, pucks, andreagents protocols will consume.

EXCEPTIONS AND CONTINUATIONS

The ESP is a complicated mechanism with many possiblefailure modes. Fortunately, objects of Ruby’s Exception classallow low-level software to report errors that require unusualprocessing without requiring that every caller check for these

gThis is why unit testing is also recommended when working with stronglytyped languages.

Feature Story

conditions explicitly. Ruby’s exceptions are analogous toJava’s, but instead of its try...catch syntax, Ruby uses be-gin...rescue keywords to delineate exception handlers. Rubyexceptions are first class objects and may include associateddata and methods. One way the ESP exploits this is by defin-ing a generic SoftError exception that is passed a block ofcode to be retried a certain number of times before it isreported as an unrecoverable failure. Exception classes thatare to be automatically retried simply inherit from thisSoftError class.

A Ruby Continuation object preserves the complete stateof a processing thread. Later, a thread can restore its state tothat saved in the continuation, effectively resuming executionfrom a bookmarked point in the code. The ESP currentlyuses continuations (and open classes) to implement debug-ging breakpoints. Inserting breakpoints involves editingRuby scripts to invoke the ‘‘breakpoint’’ method wheredesired and reloading them into the interpreter. The ESPs de-bugger is merely special instance of its interactive Ruby (irb)shell, where the local and object instance variables are thoseof the method being debugged, so they may be convenientlyexamined or modified.h

Work is in progress to use continuations to implementcheckpoints that enable biochemical protocols to be resumedafter a failure occurs. Checkpoints are similar to breakpointsexcept that they do not stop execution of the current thread.The thread’s resumable state is merely saved in a continuationobject. Currently, an unhandled exception logs a detailed er-ror message and terminates the protocol. Users will soonhave the option to resume such a failed protocol from a pre-viously stored checkpoint. However, before the protocolcould be successfully resumed from a checkpoint, a userwould first need to manually clear the error and put the ESPsmechanism into the state it was in when that checkpoint wasfirst reached.

CONCLUSIONS

Over the last 3 years of the ESPs development, Ruby hasconsistently shown itself to be a pleasantly intuitive and flex-ible programming environment. In laboratory settings, theadditional simulation capabilities necessitated by Ruby’slack of static error analysis exact a small price for the in-creased flexibility and interactivity the language affords. Pro-vided sufficient computing resources are available, theinherent immediacy of dynamically typed object-orientedscripting languages dramatically accelerates software devel-opment in complex instruments. Ruby’s open classes, in

hThe GUI debuggers available for Ruby are too resource intensive for ESPsembedded target computer.

particular, foster a programming style that encourages rapidprototyping and experimentation.

ACKNOWLEDGMENTS

This project was funded in part by the Monterey Bay Aquarium Research

Institute from funds allocated by the David and Lucille Packard Foundation

and by the National Science Foundation (OCE-0314222). Any opinions,

findings, and conclusions or recommendations expressed in this material

are those of the authors and do not necessarily reflect the views of the

National Science Foundation.

REFERENCES

1. Scholin, C. Massion, G. Mellinger, E. Brown, M. Wright, D. Cline, D.

1998. The development and application of molecular probes and novel

instrumentation for detection of harmful algae. Ocean Community Confer-

ence ’98 Proceedings, Marine Technology Society, Vol. 1 pp. 367e370.

2. Scholin, C. A., Massion, E. I. Wright, D. K. Cline, D. E. Mellinger, E.

Brown, M. 2001. Aquatic autosampler device. US Pat. No. 6187530.

3. Babin, M.; Cullen, J. J.; Roesler, C. S.; Donaghay, P. L.; Doucette, G. J.;

Kahru, M.; Lewis, M. R.; Scholin, C. A.; Sieracki, M. E.; Sosik, H. M.

New approaches and technologies for observing harmful algal blooms.

Oceanography 2005, 18, 210e227.

4. Goffredi, S. K.; Jones, W.; Scholin, C.; Marin, R.; Hallam, S.; Vrijen-

hoek, R. C. Molecular detection of marine larvae. Mar. Biotechnol

2005, 8, 1e12.

5. Scholin, C.A.; G.J. Doucette,; A.D. Cembella. In press. Prospects for

developing automated systems for in situ detection of harmful algae and

their toxins. In: M. Babin, C.S. Roesler and J.J. Cullen (eds.) Real-Time

Coastal Observing Systems for Ecosystem Dynamics and Harmful Algal

Blooms, UNESCO Publishing, Paris, France.

6. Scholin, C.; Marin, R.; Miller, P.; Doucette, G.; Powell, C.; Howard, J.;

Haydock, P.; Ray, J. Application of DNA probes and a receptor binding

assay for detection of Pseudo-nitzschia (Bacillariophyceae) species and

domoic acid activity in cultured and natural samples. Journal of Phycol-

ogy 1999, 35, 1356e1367.

7. Scholin, C. A.; Miller, P.; Buck, K.; Chavez, F.; Harris, P.; Haydock, P.;

Howard, J.; Cangelosi, G. Detection and quantification of Pseduo-

nitzschia australis in cultured and natural populations using LSU rRNA-

targeted probes. Limnology and Oceanography 1997, 42, 1265e1272.

8. Scholin, C. A.; Buck, K. R.; Britschgi, T.; Cangelois, J.; Chavez, F. P.

Identification of Pseduo-nitzschia australis (Bacillariophyceae) using

rRNA-targeted probes in whole cell and sandwich hybridization formats.

Phycologia 1996, 35, 190e197.

9. Thomas, D.; Fowler, C.; Hunt, A. Programming Ruby: The Pragmatic

Programmers’ Guide 2nd edition; pp. 329e330, ISBN 0-9745140-5-5.

JALA February 2007 61