Archive for the ‘blog’ Category

Ready? Steady? Start your business!

Thursday, July 1st, 2010

Over the last few months we have seen a number of people thinking about setting up their own micro enterprise or small business. Although Biolauncher’s clients are usually high growth potential businesses that need venture capital to grow, we have learnt a few things about running our own business over the last nine years. Having enjoyed one such discussion this morning with a potential new life science consulting company, here are some pointers to get you thinking about and ready to start your (science based) business.

Schrödinger’s cat and business start up – Like the health of the physicist’s feline trapped for ever in that thought experiment, you can only be certain about the viability business idea when you act upon it. It is important to canvas and consider opinion from trusted parties but finding reasons not to do something is much easier than finding the reason to just do it. Equally you can debate the ideal time for starting a new business, but the reality is your time may be right now. Remember if you operate as a microenterprise you can adapt and refine your business as you develop.

From thinking to doing – Our advice is if you want to be taken seriously as a business, start behaving like a business. Work out your start up budget. You will need to decide on a (memorable) name, find an accountant and get registered and register and build your website. We recommend that you register both the .com and the .co.uk address. It is a signal of intention and global engagement. You will also need a basic website, this should not cost a lot of money, and if the site is built in Wordpress you can integrate your site into the wider world of social media for next to nothing. Plan your launch and goals for the first 100 days of the business.

Now for networking – We still remember our first networking forays, and how hard it is to walk into a room full of strangers with a pocket of new business cards. Get over it – most people in the room feel exactly the same. So walk up to someone and introduce yourself and ask them a question about them. Try and think of a few icebreaker questions before you enter the room – “what are you hoping for from this event?” is a safe opening gambit.

Remember that you need to circulate around the room. If you are enjoying the conversation, use the need to move on as a reason to get their card and agree to follow up and meet another time.

There are a lot of free networking events, in the first place aim for quantity not quality. Get out there and find out what people need.

Business Card Marketing – At Biolauncher most often it is our business card that is the intro to the business, the company brochure and leave behind. It is pretty much the ONLY printed material the business uses. Small businesses can make their cards work much harder than your contact details. Moo print enables you to put product shots, customer testimonials, or just about anything on the back of your cards, you can even get a free sample pack, so no excuses for turning up at a networking event without a card. Biolauncher prints everyone’s cards in portrait and landscape format with different graphic representations of our logo on the back. By asking which card format or reverse design someone prefers recipients spend more time looking at our logo. It builds brand recognition and there is a full set to collect ;) .

Lean marketing – if you are pre revenue or pre VC you need to think about how you market your business with minimal cash outlay. There are lots of great tips out there on the internet search for “lean marketing”. You also need to develop your Social Media skills. If you run a Wordpress blog you can integrate it directly to a LinkedIn company page. If you sync your twitter account and personal LinkedIn account your status line will update to show your tweets. Post your PowerPoint presentations to Slideshare.net and embed them in your website and tweet the URL to all your followers. Look for opportunities to speak at events or put up a poster/roller banner.

Useful Links

A great value and talented Wordpress developer Kirsty Burgoine
Moo Business Cards and tips for using them
Budget Roller banners £45.00 (special offer)

Global Networks Help Fund Successful Life Science Businesses

Tuesday, June 15th, 2010

A few weeks ago Rowan presented at the excellent Babraham Investment forum in Cambridge, UK. For once we were pitching for hearts and minds instead of cold hard cash for our cause. We were highlighting the need for greater participation of women entrepreneurs in high growth business, and the excellent work of the Global Astia Network.

Astia is a global business network that operates on a lean, not for profit basis. The organisation has an exceptional track record of success (see the presentation below) and one that is well worth bringing to the UK/European market. BioLauncher volunteers time to Astia cause because we regularly encounter clients that have challenges with globalising, funding or scaling their business. A global network can provide the advice and connections to achieve these goals and therefore increase business value. We also recognise that Astia promotes diversity in management teams, so it is not a women only network.

The first Doing IT Right programme and subsequent Astia Investment Forum was held in London in 2009. Helena Kyttari Djupesland, CEO of Optinose was one of our presenters. This week, Optinose secured $48.5M from New York based Avista Capital Partners, a huge success which was well deserved. The deal is also an eloquent demonstration of how European companies need to access the US capital markets.

Next week, the second annual Astia Investment Forum will be held in London. It will be an excellent opportunity to see some of the most promising women led businesses, and meet the Astia executive and advisers. Simon Walker, Chief Executive Officer, British Venture Capital Association will also make a keynote presentation. Bona fide investors can register here.

To keep in touch with the Astia’s development in the UK and keep up to date follow @astiaUK and @vosmek on Twitter of become a friend of Astia on Facebook. Alternatively get in touch with Katie Nittler (Katie@astia.org) who leads the Astia programme in the UK.

Interactive Map of Global Biopharmaceutical Manufacturing Sites

Wednesday, June 9th, 2010

As I posted last week, we have been developing an interactive map of global biopharmaceutical manufacturing and distribution sites. This was originally inspired by a posting in the Professionals in Pharmaceutical Industry and Biotech Industry group on LinkedIn and we have used some of the ShowcaseBio tools to draw together and present the data. We will hopefully be extending this as we get more data and keeping it up to date, so please check back to see how the map develops.

You can see the map here

The data can be sliced and diced by clicking on the boxes below the map, making it easy for example to find API manufacturing sites in Singapore with support for specific bioprocessing procedures and full commercial GMP certification.

Of course this is a fairly basic example of ShowcaseBio’s data integration, analysis and presentation capabilities. We use this regularly on our customer projects to provide rich evidence bases that can be interrogated to define strategy and support real business decisions. We will be posting more examples of some of the work we do with ShowcaseBio in the future on this blog, so keep an eye out.

Global Investment in Bioprocessing 1998-2008

Wednesday, June 2nd, 2010

Mapping Investment in an Industry

A little while ago we were asked to pull together a map of foreign direct investment in bioprocessing capability made around the globe in the previous decade. We wanted to know how difficult it would be for a region to make a difference to the competitiveness of its bioprocessing industrial capacity and skills and what form that intervention might take.

Using a variety of sources from news feeds, web sites, directories and personal information we pulled together the map that you see at the bottom of this article. It became clear pretty quickly that the scale both of the investments and the associated incentives would dwarf anything that could realistically be offered. In total over that decade at least $12B was invested in new plant with approximately $3.6B of declared incentives. Other incentives in the form of tax reliefs, land/plant deals and competitive corporate tax rates would add significantly to this number over the lifetime of the investment.

The data are interesting to play with, and you may know of deals that we missed or that have happened since we did the analysis. The version in this post is just a static image, but there is an interactive version of the map here

The real map is interactive, so you can subselect bits of the information that you are interested in, e.g. just to show fill and finish facilities for small molecule products or manufacturing sites for vaccine production. Just click on the lists at the bottom (underneath the map) to select the bits you are interested in. Click on a spot on the map to find out a bit more about the investment.

I am in the process of pulling together a more complete map of all biopharmaceutical manufacturing and processing facilities as part of a LinkedIn discussion in the Professionals in Pharmaceutical Industry and Biotech Industry group. The good folks there have identified about 500 sites worldwide, and I’ve said I will map them for them once we have sufficient data, so check back in a while for the updated map.

Bioprocessing manufacturing investments from 1998-2008

Bioprocessing manufacturing investments from 1998-2008

Interactive version of the map here

Ontologies, Semantic Data Integration and Semantic Web

Monday, May 10th, 2010

I’ve just been contributing to a long discussion in the Semantic Web group of LinkedIn (check it out in full here – subscription to the group is required).  It reminded me that there are still fundamental differences about what the semantic web is, could be, and is for.

Quite a while ago now I wrote a series of articles on our experience of developing large scale semantic systems for drug discovery and drug development work.  You can find the links either at Slideshare or directly as PDFs on this site:

DDT – Ontologies and Drug Discovery (http://slidesha.re/d8GqQV)

DDT – Ontologies and Semantic Data Integration (http://slidesha.re/d0z4j3)

DDW – Ontologies: Networks of Pharmaceutical Knowledge (http://slidesha.re/c7btI5)

To give a flavour of my perspective in the LinkedIn discussion, here is my initial answer:

“Depends whether you are a computer scientist, linguist or philosopher – and therein lies the problem. Semantics is about understanding the meaning of information and as Rudy says this is inherently subjective depending on the context that the objects are observed in and the experience of the observer, and voila we’re back to semiotics, ontology and epistemology.

As someone specializing in semantic search, a really big thing to bear in mind here is that most semantic web stuff focuses on the objects themselves, giving them unique identifiers and tags of their attributes. The more useful thing about ‘truly’ semantic applications is when you can start to understand more of the nuance of the relationships between objects in a given context. My standard example is a glass of wine sitting on a table. You could classify this as a clear drinking vessel for most contexts, but in a bar fight it becomes a lethal weapon. Same object, different context, very different experience.

The true goal of semantic applications is to be able to bring a user to a set of data aggregated and integrated from a wide variety of sources and let them find the information that is relevant to them (the right objects in the right context with sufficient trustworthy evidence) and let them visualize and use it in ways that make sense to them.

We do this everyday in our heads – a good example is planning a night out on the town, integrating train and bus timetables, cinema listings and restaurant reviews and plotting everything in the context of a timeline and geolocation. We are beginning to get mashups of this type where there are common semantic maps (a literal Google maps being a good starting point), but we can also do it is chemistry, and parts of biology now to a reasonable degree. What we need are good starting points (defined domain nomenclatures – note not always necessarily ontologies in a CS sense) and tools that let us map these together.

We also need a cultural shift – we have become so Google bound that we can’t see the results for the tool. Very quick example – drug researchers spend a lot of time looking for info in scientific literature. They use keyword search tools including Google. They seem happy to get back 3 million hits to a simple query like ‘Which compounds cause asthma’ and then reading through a few hundred abstracts to convince themselves of the answer (obviously ignoring the vast bulk of the hits). In fact the answer is about 500 give or take, and a semantic search tool can get you there instantly and (if done well) its answers are very nearly complete. Interestingly that seems to freak people out a bit as they seem to think this is less comprehensive than the Google search that gave them 2.999 million wrong or redundant hits. Go figure – back to epistemology… ;-)

Databases in the Cloud: Amazon Web Services Relational Database Server (AWS RDS)

Saturday, March 27th, 2010

Taking Advantage of Cloud Based Database Deployment

As many of you will know, one of my passions is semantic data integration.  I have been developing the ShowcaseBio system to integrate some really interesting life science company, technology and people data.  ShowcaseBio is now pretty large (over 40GB) for a local server bound system and as we are routinely doing more interesting text analytics and larger scale data mining, we are starting to need a bit more compute power than we have to hand.  As I was toying with how to drop the bombshell to Dirk and Rowan that I wanted to spend some serious money on kit, I found what looks to me like the ideal solution.

Amazon has recently put into beta a scalable MySQL 5.1 implementation on their AWS cloud called AWS RDS.  You can store 5GB-1TB data in a sliding scale of database instance classes ranging from 1-26 ECUs and 1.7-68GB RAM.  You get charged for the up-time and data transfers in and out, but they look after the backups, snapshots and maintenance/updating. If you find that you are CPU or memory bound, you can simply jump up to the next instance class and pay a bit more.  Sounds perfect I thought, so I took a peek at it.  And once I’d got through the slightly difficult documentation and longwinded nomenclature, I must admit that I’m pretty impressed.

Here’s what I found and a practical guide to getting started with programmatic access to AWS RDS using C#.

How To Create, Write To and Query an AWS RDS Database (in C#)

The very first thing you will need to do is to sign up for the service.  You will get in return a public and private key pair which you will need later for both the command line and C# tools.  You will also need to install the AWS SDK and of course the MySQL dll if you haven’t already got this.

The first thing to say is that the example code provided on the AWS RDS site (at least for C#) is out of date and uses an SDK version that has been deprecated.  It also deals mainly with examining the metadata around the service rather than how touse it in anger (hence this post).

The SDK docs are up-to-date though and installation of the AWS SDK in Visual Studio (VS2008)  is a doddle.  The next thing to stress is that it is very helpful to install the command line tools that Amazon provide. They will help you monitor what is going on and make doubly sure you don’t leave any test instances running (and accruing charges!).  You are going to need two main commands:

rds-describe-db-instances --headers
// This displays the status of all current database instances
rds-delete-db-instance --db-instance-identifier testdbinstance --skip-final-snapshot
// This kills any stray testdbinstances that might be lying around

Once you have the command line up and running, you can build the little test application described below.  It’s going to take you through the basics of setting up an RDS client service, setting up access via security groups, creating an AWS RDS database instance, getting the remote MySQL connection string, and then creating a table and writing to/reading from it.

For those who like to skip ahead, the code is here, otherwise here is the app in use:

Opening screen

AWS RDS test app opening screen

Waiting for the ASW RDS instance to become available

Waiting for the ASW RDS instance to become available

Created table on remote database instance

Created table on remote database instance

Writing and reading to remote database table on AWS RDS

Writing and reading to remote database table on AWS RDS

This is the opening screen before connecting to AWS RDA and creating a database.  If you hit the Open DB button, it will create an RDS client service with appropriate security access and create a database instance named ‘testdbinstance’ on the AWS RDS cloud.  Given it is setting up a whole MySQL instance, this is not quick – it can take 3-4 minutes for the instance to be available and about the same for it to be deleted.  As well as monitoring progress on the command line, you can track when the instance becomes available on the status bar of the app.

Once the remote instance is available you will see its name, remote server and port number in the status bar.  You can then hit the Create Table button, which will create a test table on the remote database.  You will see that a single row has appeared in the DataGridView.  This is the first empty row that you get back from a SELECT * FROM table query when there is no data in it.

You can then have fun hitting the Insert New Row button which will INSERT INTO the test table to create new row entries in the test table on the remote database.  Finally you can hit the Close DB button to delete the remote database instance (without saving a snapshot).

When you use it you will find that once you have the MySQL connection string, the system (unsurprisingly I suppose) behaves just like any other MySql implementation, so no code/schema changes and many of the headaches of managing performance are allevaited a little.  You’ll find that it plays nicely with EC2 apps as well as an added bonus…

Have fun!

Important Reminder

At this stage it’s good to remember that AWS RDS is a commercial service and Amazon will of course charge you for any time that your db instance is up, so if you’re just trying it out, be sure to close it down either with the app or the command line interface before you finish!

C# Code

You can download a (partial) VS 2008 project here.  You will still have to install the MySQL and AWS SDK components and supply your AWS account information.

The C# code is shown below.  Apologies that the formatting has gone a bit awry, but if you stick it in VS2008 it will reformat properly.  You will need 4 things to make it work (beyond the usual VS2008/.Net 3.5 environment), namely the usual MySql dll, your public and private keys for the AWS RDS service and one or more IP ranges (in CIDR-IP format) for which you wish to enable access to your test database.  How to get the keys is covered in the AWS RDS documentation.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using MySql.Data.MySqlClient;
using Amazon.RDS;

namespace AWS_RDS_Test
{
 public partial class Form1 : Form
 {
 public string RDSConnection = "";
 public string myPublicKey = "";                    // INSERT YOUR PUBLIC KEY HERE //
 public string myPrivateKey = "";                   // INSERT YOUR PRIVATE KEY HERE //
 public Amazon.RDS.Model.IPRange ip1 = new Amazon.RDS.Model.IPRange();
 public Amazon.RDS.Model.IPRange ip2 = new Amazon.RDS.Model.IPRange();
 public Amazon.RDS.AmazonRDSClient RDS;
 public Amazon.RDS.Model.CreateDBInstanceResponse response;
 public Amazon.RDS.Model.CreateDBInstanceResult result;
 public Amazon.RDS.Model.DBInstance db;
 public MySqlConnection connection;

 public Form1()
 {
 InitializeComponent();
 }

 private void openDB_Click(object sender, EventArgs e)
 {                                                  // Insert IP addresses to be given access
 ip1.Status = "authorized";                         // using CIDR-IP definitions
 ip2.Status = "authorized";                         // of the form xxx.xxx.xxx.xxx/yy e.g. "192.168.0.1/30" (but external IP)
 ip1.CIDRIP = "";                                   // INSERT YOUR IP ADDDRESS HERE //
 ip2.CIDRIP = "";                                   // INSERT YOUR IP ADDRESS HERE //

 createRDS();                      // Create the RDS service using the public/private keys in the public variables 

 Amazon.RDS.Model.CreateDBInstanceRequest request = new Amazon.RDS.Model.CreateDBInstanceRequest();
 request.DBName = "testdb";                         // Name of the database to be created e.g. testdb
 request.AllocatedStorage = 5;                      // Amount (GB) of storage required - INT between 5-1024
 request.BackupRetentionPeriod = 0;                 // How long to keep backups (days), 0 = no backups
 request.DBInstanceClass = "db.m1.small";           // How much CPU & memory to allocate - Valid values: db.m1.small | db.m1.large | db.m1.xlarge | db.m2.2xlarge | db.m2.4xlarge
 request.DBInstanceIdentifier = "testdbinstance";   // The name of the db instance to be created
 request.Engine = "MySQL5.1";                       // The name of the database engine to be used -  MySQL5.1 is only valid value
 request.MasterUsername = "testadmin";              // The admin user name
 request.MasterUserPassword = "testpassword";       // The password for the admin user (alphanumeric only)

 createRDSDB(request);            // Create the database instance on the RDS service
 }

 private void closeDB_Click(object sender, EventArgs e)
 {
 if (db != null)                            // Make sure there is actually something to delete
 {
 if (db.IsSetDBInstanceIdentifier())
 {
 deleteRDSDB(db, false);
 RDS.Dispose();
 }
 }
 }

 private void createTable_Click(object sender, EventArgs e)
 {
 createRDSTable(db.DBName, "TestTable", "TestCol");
 }

 private void insertRow_Click(object sender, EventArgs e)
 {
 insertDBRow(db.DBName, "TestTable", "TestCol", "The time is " + DateTime.Now.ToLongTimeString());
 }

 private void Form1_FormClosing(object sender, FormClosingEventArgs e)
 {                                              // Delete the testdb instance to avoid being charged when closing down
 if (db != null)                            // Make sure there is actually something to delete
 {
 if (db.IsSetDBInstanceIdentifier())
 {
 deleteRDSDB(db, false);
 RDS.Dispose();
 }
 }
 }

 private void createRDS()
 {
 Amazon.RDS.Model.DescribeDBSecurityGroupsResult secGroupsResult = new Amazon.RDS.Model.DescribeDBSecurityGroupsResult();
 List<Amazon.RDS.Model.IPRange> ipRange = new List<Amazon.RDS.Model.IPRange>();   // Create the collection of allowable IP ranges 

 // Create a new RDS service client with appropriate IP address based security group so we can access it via code later
 RDS = new Amazon.RDS.AmazonRDSClient(myPublicKey, myPrivateKey);                        

 secGroupsResult = findSecurityGroups(myPublicKey + "_default");                 // Delete any existing security groups
 deleteSecurityGroups(secGroupsResult);

 ipRange.Add(ip1);                                                               // Add the IP addresses to the IPRange List
 ipRange.Add(ip2);

 addSecurityGroup(myPublicKey + "_default", "Default access group", ipRange);    // Add in the new security groups
 // with a likely unique name
 }

 private Amazon.RDS.Model.DescribeDBSecurityGroupsResult findSecurityGroups(string groupName)
 {
 Amazon.RDS.Model.DescribeDBSecurityGroupsRequest secGroupsRequest = new Amazon.RDS.Model.DescribeDBSecurityGroupsRequest();
 Amazon.RDS.Model.DescribeDBSecurityGroupsResponse secGroupsResponse = new Amazon.RDS.Model.DescribeDBSecurityGroupsResponse();

 secGroupsRequest.DBSecurityGroupName = groupName;                                 // Find all matching DBSecurity groups
 try { secGroupsResponse = RDS.DescribeDBSecurityGroups(secGroupsRequest); }
 catch (AmazonRDSException ex)
 {
 if (ex.ErrorCode != "DBSecurityGroupNotFound")
 MessageBox.Show("Caught Exception: " + ex.Message + "\r\nResponse Status Code: " + ex.StatusCode + "\r\nError Code: " + ex.ErrorCode + "\r\nError Type: " + ex.ErrorType + "\r\nRequest ID: " + ex.RequestId + "\r\nXML: " + ex.XML);
 }

 if (secGroupsResponse.IsSetDescribeDBSecurityGroupsResult())
 return (secGroupsResponse.DescribeDBSecurityGroupsResult);                         // and return them
 else
 return (null);

 }

 private void deleteSecurityGroups(Amazon.RDS.Model.DescribeDBSecurityGroupsResult groups)
 {
 if (groups != null)
 {
 Amazon.RDS.Model.DeleteDBSecurityGroupRequest secDeleteRequest = new Amazon.RDS.Model.DeleteDBSecurityGroupRequest();
 Amazon.RDS.Model.DeleteDBSecurityGroupResponse secDeleteResponse = new Amazon.RDS.Model.DeleteDBSecurityGroupResponse();

 foreach (Amazon.RDS.Model.DBSecurityGroup sg in groups.DBSecurityGroup)       // Iterate over groups
 {
 secDeleteRequest.DBSecurityGroupName = sg.DBSecurityGroupName;
 try { secDeleteResponse = RDS.DeleteDBSecurityGroup(secDeleteRequest); }  // and delete them all
 catch (AmazonRDSException ex)
 { MessageBox.Show("Caught Exception: " + ex.Message + "\r\nResponse Status Code: " + ex.StatusCode + "\r\nError Code: " + ex.ErrorCode + "\r\nError Type: " + ex.ErrorType + "\r\nRequest ID: " + ex.RequestId + "\r\nXML: " + ex.XML); }
 }
 }
 }

 private void addSecurityGroup(string groupname, string groupdescription, List<Amazon.RDS.Model.IPRange> ipRange)
 {
 Amazon.RDS.Model.CreateDBSecurityGroupRequest secRequest = new Amazon.RDS.Model.CreateDBSecurityGroupRequest();
 Amazon.RDS.Model.CreateDBSecurityGroupResponse secResponse = new Amazon.RDS.Model.CreateDBSecurityGroupResponse();
 Amazon.RDS.Model.CreateDBSecurityGroupResult secResult = new Amazon.RDS.Model.CreateDBSecurityGroupResult();
 Amazon.RDS.Model.AuthorizeDBSecurityGroupIngressRequest authIngressRequest = new Amazon.RDS.Model.AuthorizeDBSecurityGroupIngressRequest();
 Amazon.RDS.Model.AuthorizeDBSecurityGroupIngressResponse authIngressResponse = new Amazon.RDS.Model.AuthorizeDBSecurityGroupIngressResponse();
 Amazon.RDS.Model.AuthorizeDBSecurityGroupIngressResult authIngressResult = new Amazon.RDS.Model.AuthorizeDBSecurityGroupIngressResult();

 secRequest.DBSecurityGroupName = groupname;                                            // Name for security group
 secRequest.DBSecurityGroupDescription = groupdescription;                              // Simple description of security group

 try { secResponse = RDS.CreateDBSecurityGroup(secRequest); }                           // Check we can create the security group
 catch (AmazonRDSException ex)
 { MessageBox.Show("Caught Exception: " + ex.Message + "\r\nResponse Status Code: " + ex.StatusCode + "\r\nError Code: " + ex.ErrorCode + "\r\nError Type: " + ex.ErrorType + "\r\nRequest ID: " + ex.RequestId + "\r\nXML: " + ex.XML); }

 if (secResponse.IsSetCreateDBSecurityGroupResult())
 {                                                                                      // Get the security group results
 secResult = secResponse.CreateDBSecurityGroupResult;
 secResult.DBSecurityGroup.IPRange.AddRange(ipRange);                               // Add the IP ranges to the security group properties
 authIngressRequest.DBSecurityGroupName = secResult.DBSecurityGroup.DBSecurityGroupName;
 foreach (Amazon.RDS.Model.IPRange ip in ipRange)                                   // Allow access from each IP range
 {
 authIngressRequest.CIDRIP = ip.CIDRIP;

 try { authIngressResponse = RDS.AuthorizeDBSecurityGroupIngress(authIngressRequest); }
 catch (AmazonRDSException ex)
 { MessageBox.Show("Caught Exception: " + ex.Message + "\r\nResponse Status Code: " + ex.StatusCode + "\r\nError Code: " + ex.ErrorCode + "\r\nError Type: " + ex.ErrorType + "\r\nRequest ID: " + ex.RequestId + "\r\nXML: " + ex.XML); }

 if (authIngressResponse.IsSetAuthorizeDBSecurityGroupIngressResult())
 authIngressResult = authIngressResponse.AuthorizeDBSecurityGroupIngressResult;
 }
 }
 }

 private void createRDSDB(Amazon.RDS.Model.CreateDBInstanceRequest request)
 {
 bool makenew_dbinst = true;
 Amazon.RDS.Model.DescribeDBInstancesRequest instRequest = new Amazon.RDS.Model.DescribeDBInstancesRequest();
 Amazon.RDS.Model.DescribeDBInstancesResponse instResponse = new Amazon.RDS.Model.DescribeDBInstancesResponse();
 Amazon.RDS.Model.DescribeDBInstancesResult instResult = new Amazon.RDS.Model.DescribeDBInstancesResult();
 Amazon.RDS.Model.Endpoint e = new Amazon.RDS.Model.Endpoint();

 instResponse = RDS.DescribeDBInstances(instRequest);       // Get the response to the DescribeDBInstances
 if (instResponse.IsSetDescribeDBInstancesResult())         // Check if we have descriptions of the DBInstances on RDS
 {                                                          // If we do, check to see if our instance already exists
 instResult = instResponse.DescribeDBInstancesResult;
 foreach (Amazon.RDS.Model.DBInstance i in instResult.DBInstance)
 if (i.DBName.Equals(request.DBName))               // If it does, we don't need to recreate it
 {                                                  // So we can resue the existing instance by
 db = i;                                        // setting db to point at the existing DB instance
 e = i.Endpoint;                                // Set e to the existing instance's endpoint
 toolStripStatusLabel2.Text = "DB: " + db.DBName + "  Server: " + e.Address + "  Port: " + e.Port.ToString();
 statusStrip1.Refresh();
 makenew_dbinst = false;                        // Set the flag to avoid trying to recreate the existing instance
 }
 }
 if (makenew_dbinst)
 {
 try
 {
 response = RDS.CreateDBInstance(request);          // If it doesn't already exist we need to create it
 if (response.IsSetCreateDBInstanceResult())        // Check that we are OK to create the instance
 {
 result = response.CreateDBInstanceResult;      // Then create it
 db = result.DBInstance;                        // and set db to be the DB instance
 // It takes 3-4 mins for the instance to be available, so we wait
 // until the endpoint information (address & port) is set
 toolStripStatusLabel1.Text = "Please wait - creating DB " + db.DBName + " ";
 toolStripProgressBar1.Visible = true;
 do
 {
 toolStripProgressBar1.Value = (toolStripProgressBar1.Value + 9) % 100;
 statusStrip1.Refresh();
 Application.DoEvents();
 Thread.Sleep(3000);                        // Check every 3 seconds to avoid throttling exception
 e = IsAvailableRDS(instRequest, request);  // Read the DBInstance data to pick up new Endpoint information
 // This is convoluted as db.Endpoint does not appear to refresh
 } while (e.Address == null);

 db.Endpoint = e;
 toolStripProgressBar1.Visible = false;
 toolStripStatusLabel1.Text = "Database " + db.DBName + " created";
 toolStripStatusLabel2.Text = "DB: " + db.DBName + "  Server: " + e.Address + "  Port: " + e.Port.ToString();
 statusStrip1.Refresh();
 }
 }
 catch (AmazonRDSException ex)
 { MessageBox.Show("Caught Exception: " + ex.Message + "\r\nResponse Status Code: " + ex.StatusCode + "\r\nError Code: " + ex.ErrorCode + "\r\nError Type: " + ex.ErrorType + "\r\nRequest ID: " + ex.RequestId + "\r\nXML: " + ex.XML); }
 }

 // Set the all important MySql connection string for the RDS DB instance

 RDSConnection = "SERVER=" + e.Address + ";DATABASE=" + request.DBName + ";Connect Timeout=300;Port=" + e.Port.ToString() +
 ";UID=" + db.MasterUsername + ";PASSWORD=" + request.MasterUserPassword;
 }

 private Amazon.RDS.Model.Endpoint IsAvailableRDS(Amazon.RDS.Model.DescribeDBInstancesRequest instRequest, Amazon.RDS.Model.CreateDBInstanceRequest request)
 {
 Amazon.RDS.Model.Endpoint e = new Amazon.RDS.Model.Endpoint();            // Check whether the requested instance is available
 Amazon.RDS.Model.DescribeDBInstancesResponse instResponse = RDS.DescribeDBInstances(instRequest);
 if (instResponse.IsSetDescribeDBInstancesResult())                        // Find the DBInstance and check if it is available
 {
 Amazon.RDS.Model.DescribeDBInstancesResult instResult = instResponse.DescribeDBInstancesResult;
 foreach (Amazon.RDS.Model.DBInstance i in instResult.DBInstance)      // Iterate over the instances
 if (i.DBName.Equals(request.DBName))                              // If we have the right one
 if (i.DBInstanceStatus == "available")                        // and it's available
 {                                                             // return its details
 e.Address = i.Endpoint.Address;
 e.Port = i.Endpoint.Port;
 }
 }
 return (e);
 }

 private void deleteRDSDB(Amazon.RDS.Model.DBInstance db, bool snapshot)
 {
 Amazon.RDS.Model.DeleteDBInstanceRequest delRequest = new Amazon.RDS.Model.DeleteDBInstanceRequest();
 Amazon.RDS.Model.DeleteDBInstanceResponse delResponse = new Amazon.RDS.Model.DeleteDBInstanceResponse();

 delRequest.DBInstanceIdentifier = db.DBInstanceIdentifier;            // Find the right db instance to delete
 delRequest.SkipFinalSnapshot = !snapshot;                             // Decide whether to write snapshot or not
 if (snapshot)
 delRequest.FinalDBSnapshotIdentifier = db.DBName;
 delResponse = RDS.DeleteDBInstance(delRequest);
 if (delResponse.IsSetDeleteDBInstanceResult())                        // See whether it is OK to delete instance
 try                                                               // If so delete it
 {
 Amazon.RDS.Model.DeleteDBInstanceResult delResult = delResponse.DeleteDBInstanceResult;
 toolStripStatusLabel2.Text = "DB: -  Server: -  Port: -";
 statusStrip1.Refresh();
 }
 catch (AmazonRDSException ex)
 { MessageBox.Show("Caught Exception: " + ex.Message + "\r\nResponse Status Code: " + ex.StatusCode + "\r\nError Code: " + ex.ErrorCode + "\r\nError Type: " + ex.ErrorType + "\r\nRequest ID: " + ex.RequestId + "\r\nXML: " + ex.XML); }
 }

 private void createRDSTable(string database, string tablename, string column)
 {
 openRDSDB();

 MySqlCommand command = connection.CreateCommand();

 command.CommandText = "CREATE TABLE " + database + "." + tablename + " (" + column + " varchar(255) NOT NULL);";

 try { command.ExecuteNonQuery(); }
 catch { MessageBox.Show("Table already exists (or other error): " + command.CommandText); }

 closeRDSDB();

 updateDataGrid(database, tablename);
 }

 private void insertDBRow(string database, string tablename, string column, string value)
 {
 openRDSDB();

 MySqlCommand command = connection.CreateCommand();

 command.CommandText = "INSERT INTO " + database + "." + tablename + " VALUES ('" + value + "')";

 try { command.ExecuteNonQuery(); }
 catch { MessageBox.Show("Cannot INSERT: " + command.CommandText); }

 closeRDSDB();

 updateDataGrid(database, tablename);
 }

 private void updateDataGrid(string database, string tablename)
 {
 openRDSDB();
 // Populate datagrid with data from the RDS database
 MySqlDataAdapter MySqlDA = new MySqlDataAdapter("SELECT * FROM " + database + "." + tablename, RDSConnection);

 DataTable table = new DataTable();                                 // Populate a new data table from the db
 table.Locale = System.Globalization.CultureInfo.InvariantCulture;
 MySqlDA.Fill(table);                                                 

 dataGridView1.DataSource = table;                                  // and bind the DataGrid to it
 dataGridView1.Columns[0].HeaderText = "Value";
 dataGridView1.Columns[0].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;

 closeRDSDB();
 }

 private void openRDSDB()
 {
 connection = new MySqlConnection(RDSConnection);

 try { connection.Open(); }
 catch
 {
 MessageBox.Show("Cannot open connection to: " + RDSConnection);
 Close();
 }
 }

 private void closeRDSDB()
 {
 if (connection != null)
 connection.Close();
 }

 }
}
// Define some allowable IP ranges

Grabbing £2.7M Grant Funding to Bridge to Finance

Friday, March 26th, 2010

We have been doing a lot of work on behalf of clients seeking to attract grant funding recently. Just last week Dirk Gewert begin_of_the_skype_highlighting     end_of_the_skype_highlighting found out that he had successfully shepherded four Technology Strategy Board (TSB) applications through the application process. Two were awarded and two were invited to submit full applications. In the last 9 months Dirk has helped clients win 5 TSB awards that will fund a total of £2.7M of projects.

In the current investment climate that is real money, and it is helping companies demonstrate and develop their activity to a point where it can attract funding from venture capitalists. It is also helping companies stretch their runway.

Our advice to clients thinking about using grant funding to finance your business is make sure the grant will fund activity that is on the critical path. Grant funding may seem like “free money” but there is an opportunity costs associated with committing management time and company resources to noncore and nice to have activity. The administration overhead quickly becomes costly if you not driving the business forward.

There are a number of grant funding opportunities that UK SMEs can consider, i4i, Technology Strategy Board competitions, Grant for R&D and Eurostars. None of these funding sources are as competitive currently as the venture capital markets.

There are number of opportunities to find out more. Technology Strategy Board has an event next week in London (30th March 2010).  You can meet award winners and find out about their experience of using TSN competition funding to advance their business. TSB is also running an event in April aimed at informing life science SMEs and Universities about funding opportunities from Europe, find our more here.

If you are struggling to find a partner, you can get in touch with the KTN or pick up the phone to BioLauncher. We have helped clients build collaborations and can use ShowcaseBio to identify potential partners in the UK or internationally.

Where are the Women Led Life Science Businesses in Europe?

Tuesday, March 9th, 2010

This week Astia – a global non-profit organization that provides innovative programs to exceptional women-led start-ups – announced the dates for its second annual ‘Doing it Right’ London Programme. Read the Announcement here:

Astia is an unusual organisation that delivers its support and leadership services through a network of 750 serial entrepreneurs, investors and advisors. Head-quartered in San Francisco, Astia delivers programs for entrepreneurs in Silicon Valley, New York, London and, from 2010, India.

Astia’s focus in London in preparing client entrepreneurs to access and secure capital. However the value of the global network is that it provides a mechanism to scale women led businesses by connecting to overseas capital and gaining introductions to partner organisations beyond the immediate payoff of the event participation.

Astia is currently reaching out to high potential women led businesses in high potential sectors including life sciences. There are very few companies in our sector led by women. That is a something that we all need to address; because

    1) we are educating more women scientists and entrepreneurs. If this pool of talent cannot be translated into business leaders we compromise our capacity to improve GDP.

    2) Evidence suggests that women led businesses are more capital efficient and less likely to fail

If you would like to find out more about Astia’s activities in Europe, please visit the website. If you are a women led business Astia would like to hear from you. Please feel free to contact one of the Astia team or pick up the phone to Rowan at BioLauncher.

And if you are considering starting a business follow the advice of Anne Lauvergeon, CEO of Areva and ranked the most by Forbes as one of the world’s ten most powerful women, ahead of Michelle Obama, Hillary Clinton and the Queen.

In a recent interview with The Times she was asked – What advice would you give to young women entering business? Her answer “You can do it. When I was 20 I would never have imagined that I would be a CEO.”
You can read that interview here:

How Time and Technology Flies on the Web

Thursday, February 4th, 2010

My first experience of building a company website was 1994, for Oxford Molecular Group.  Fast forward to 2010 and I am amazed by the rich possibilities of using the internet to connect with your market.  And more interestingly the small price that you need to pay to acquire them.

At Biolauncher we have been working with revenue generating companies to help develop their commercial strategy. We have helped secure distribution deals, strategic partnerships, collaborative funding as well as deploy automated sales force management systems and e-marketing tools.  We also recognised the need to practise what we preach within Biolauncher.  The time had come to be more open about the wide range of our activities and talk about the success we have been building with our clients.

This new website was a key component of our new approach. Once our new corporate identity and website was designed by John McCarthy (www.actionidea.com), we faced the task of how to implement the site.  We were keen to use a content management tool to make updating the site easier and more manageable.  However quotes for proprietary hosted solutions seemed expensive and restrictive. Open source systems such as Joomla and Drupal were powerful, but required too much effort to set up in house and were over specified for our needs.

We turned to our network for advice – and we were soon on the right path.  A catch up meeting with an old colleague John Woods (www.linkdex.com) who is now active in Internet analytics and SEO technologies steered us towards Wordpresss.org and some useful links helped us understand the scope of the technology.  A conversation with Darika Ahrens (www.grapevine-consulting.com) social media expert and online branding experts pointed us at Elance (www.elance.com), an online procurement site which provides an escrow based contracting service and access to a global network of freelance experts.

So armed with a graphic specification we paid our $10 to join the club and uploaded our brief to Elance.  Within 15 minutes we had our first proposal.  By mid afternoon we had 25 costed proposals, all of whom were promising to deliver the site within three weeks. Bids came in from China, India, Uzbekistan, USA and UK ranging in cost from $600-$1,600.  We chose a developer based in Boston, MA based on his approach and his communication skills. We think David Nunez (www.davidnunez.com) did a great job and delivered the project 3 weeks faster than using a traditional approach.  Our total project saving was £2,000.

If you want to pick our brains, our networks or discuss the Elance approach, get in touch.  It costs nothing to start a conversation with us.