Grails’ ease-of-use makes it an ideal framework for rapid application development. In most businesses governed by the simple Time = Money equation, the ability to quickly create a fully functional web application that can be deployed on the Java platform is a no-brainer, even for the non-technical set. However, in the biotech and pharmaceutical industries where Time = Lives, Grails becomes an even more compelling framework.
I know that sounds like I just regurgitated a marketing pitch, but bear with me for a minute while I give you a concrete example from the world of drug discovery.
One of the primary activities in a drug discovery informatics group is to support assay development groups. Chemists typically develop and implement new experiments (known as assays) used to identify and characterize potential drug-like compounds. There are two basic types of assays: plate-based assays and non-plate-based assays, and each usually stores data differently.
Plate-based assays are usually high-throughput in nature. Anything from 96, 384, to 1536 wells worth of data for each plate. Each well contains a single experiment for which you’re collecting data, and many of the wells need to be acted upon collectively. For example, if you are trying to determine the concentration where a compound demonstrates the ability to inhibit a protein, you create a dilution series where each well in a row or column on a plate contains a smaller or higher concentration of the compound. Each of the wells in the dilution series is then used to calculate an IC50 (inhibition concentration 50%). The schema that results from this is known as a “long-skinny” because you typically have a table with only a few columns — one data column and metadata columns for the plate, well, compound id, and batch id.
Non-plate based assays are usually low throughput, but you tend to collect more data points per experiment. And typically you find yourself using an Entity Attribute Value (EAV) type schema to store this kind of information.
In either case, you end up doing a lot of extra work to create “rollups” — basically stored procedures to flip the results into a more columnar format. After doing rollups for the better part of a year, I recognized the pain in one developer’s blog when he admitted that if he had it to do over again, he would have made his schema match his problem domain rather than trying to use a generic EAV schema.
OK, so what’s the alternative? Each assay is different, and has a different set of parameters to be stored. An obvious solution, might be to use a graph database like Neo4j. You can attach a variable set of attributes to any node in the graph. However, this would cause problems if you wanted to query across relational and NoSQL databases. This is often the case when you want to combine assay data with data from other internal systems. Although there is a semantic web solution for this, the solution is a little beyond the ken of most developers at the moment.
I was mulling over these problems recently and started to think about how easy it is to create applications in Grails. And it occurred to me that creating a Grails app for each assay could potentially be a viable solution, there is after all, very little overhead required in creating new applications. Most of the work would be in designing the domain objects needed by the assay, and mapping data files into the proper fields of those domain objects so that data could be easily parsed and loaded into the system. You would also want to replace the standard UI templates, with templates that are appropriate for your company.
I came up with 3 potential architectures for this Grails-based approach:
Multiple Apps/Single Database
In this approach each assay is supported by its own application, and each of these applications point to the same database. The advantage to this approach is that you get pretty good modularity. You can add support for new features to an assay without touching other applications. Since Grails makes use of Maven for modularity, each of these applications can share the same libraries and plugins. So you’re not necessarily filling up a disk with multiple copies of the same libraries. Using a single database, also has an advantage, since any report generation tools would be able to run queries across the entire database. You can deploy support for a new assay by simply deploying the WAR file containing the new assay application. Keep in mind though that Grails will begin modifying the database as soon as you start the new application in order to support the new database tables.
Multiple Plugins/Single Database
In a variation of the previous approach, we use Grails’ fantastic support for plugins to provide support for each assay. By creating each assay as a separate plugin, we’re able to create, run and test the plugin as though it were its own standalone application. To add support for a new assay, we simply install the assay as a new plugin. You have to keep in mind that you can’t do this on a running application though.
Multiple Apps/Multiple Database
In this approach you have all of the advantages of the previous approach, but you’ve further segregated the databases. Queries across database schemas are more complex to maintain and require the DBA to manage security for multiple schemas. Deployment of new applications can be done without effecting the support for other assays.
Regardless of the approach you take though, there are a number of plugins that you’d need in order to support the assay:
- Spring Security: You always need to support security.
- Navigation: Gives you a single consistent navigation bar in your apps
- Richui: Gives you support for trees, autocomplete, calendars, rich text editors and much more.
- CSV: Haven’t tried this out myself, but this should allow you to map a CSV file to a domain object (according to the docs).
- modalbox: creates a modal dialog box
- graphing plugins: There are several available including Bluff, Sparklines, Google Chart, and OpenFlash Charting. You’d need to decide which approach supports your needs best
- Export Plugin: Useful for exporting assay data in different file formats.
If you wanted to make the process of creating assay applications easier, you could bundle up all of these plugins into a new plugin and simply add that single meta-plugin to each application project.