wtorek, 24 września 2013

Playing with Thrift and Java

Thrift is an interface definition language that is used to define and create services for numerous languages, including Java. It is used as a remote procedure call (RPC) framework and was developed at Facebook.

At Intelliseq we are using thrift as a communication protocol for our genequery noSQL database. In this post I will describe basic thrift server and a test client.

First, we need to download and install thrift. See http://thrift.apache.org/.

Next we need to design our interface. This is what I like about thrift. You need to design interface first. It is my favorite approach to software architecture design. Below is a simple interface of service with enum, structure, exception and few methods. I didn't include collections, imports, one way methods and few more less important featuresof thrift. You can read more about them in this great missing guide.
namespace java pl.intelliseq.largedata.thrift

struct Message {
 1: required string message
}

struct User {
 1: required string firstname
 2: required string lastname
}

enum Wrong {
 FIRST = 1,
 SECOND = 2
}

exception InvalidFirst {
 1: string why
}

ExampleService {
 bool isAlive(),
 Message getHello(1:User user),
 void getError(1: Wrong wrong) throws (1:InvalidFirst ouch)
}

We can autogenerate code with this command. Assuming that our thrift file is in thrift subdirectory.
thrift --gen java thrift/Exampleservice.thrift
All classes were autogenerated and placed in gen-java directory. We can set this directory as src directory. Next, we will implement all methods:
package pl.intelliseq.largedata.thrift;

import org.apache.thrift.TException;

public class ThriftHandler implements ExampleService.Iface {

 @Override
 public boolean isAlive() throws TException {
  return true;
 }

 @Override
 public Message getHello(User user) throws TException {
  Message message = new Message();
  message.setMessage("Hello " + user.getFirstname() + " " + user.getLastname());
  return message;
 }

 @Override
 public void getError(Wrong wrong) throws InvalidFirst, TException {
  if (wrong.equals(Wrong.FIRST)) throw new InvalidFirst();
 }

}
We have also to set up our server. We need to run it in separate thread if we want to test it.
package pl.intelliseq.largedata.thrift;

import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.server.TServer;
import org.apache.thrift.server.TThreadedSelectorServer;
import org.apache.thrift.transport.TFramedTransport;
import org.apache.thrift.transport.TNonblockingServerSocket;
import org.apache.thrift.transport.TNonblockingServerTransport;
import org.apache.thrift.transport.TTransportException;

public class ThriftServer implements Runnable {

 TServer server;
 
 public void init() throws InterruptedException, TTransportException {
  System.out.println("Starting server on port 9090 ...");
  ThriftHandler handler = new ThriftHandler();
  ExampleService.Processor processor = new ExampleService.Processor(
    handler);
  TNonblockingServerTransport trans = new TNonblockingServerSocket(9090);
  TThreadedSelectorServer.Args args = new TThreadedSelectorServer.Args(trans);
  args.transportFactory(new TFramedTransport.Factory());
  args.protocolFactory(new TBinaryProtocol.Factory());
  args.processor(processor);
  args.selectorThreads(4);
  args.workerThreads(32);
  server = new TThreadedSelectorServer(args);

  new Thread(this).start();

  while(!server.isServing()) {Thread.sleep(1); };
  System.out.println("Serving on port 9090 ...");
 }
 
 public void run() {
  server.serve();
 }
}
And finally, we will write our test:
package pl.intelliseq.largedata.thrift;

import static org.junit.Assert.*;

import org.apache.thrift.TException;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.transport.TFramedTransport;
import org.apache.thrift.transport.TSocket;
import org.apache.thrift.transport.TTransport;
import org.apache.thrift.transport.TTransportException;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"file:conf/thrift-conf.xml"})
public class ThriftServerTest {

 TTransport transport;
 ExampleService.Client client;
 
 @Before
 public void init() throws TTransportException {
  transport = new TFramedTransport(new TSocket("localhost", 9090));
  transport.open();
  TProtocol protocol = new TBinaryProtocol(transport);
  client = new ExampleService.Client(protocol);
 }
 
 @After
 public void destroy() {
  transport.close();
 }

 @Rule
 public ExpectedException exception = ExpectedException.none();
 
 @Test
 public void isAliveTest() throws TException {
  assertTrue(client.isAlive());
 }
 
 @Test
 public void getHelloTest() throws TException {
  User user = new User();
  user.setFirstname("John");
  user.setLastname("Doe");
  assertEquals(client.getHello(user).getMessage(), "Hello John Doe");
 }
 
 @Test
 public void getErrorTest() throws TException {
  exception.expect(InvalidFirst.class);
  Wrong wrong = Wrong.FIRST;
  client.getError(wrong);
 }
 
 @Test
 public void getErrorSecondTest() throws TException {
  Wrong wrong = Wrong.SECOND;
  client.getError(wrong);
 }

}
That's it. Works like a charm. You can clone working project here: https://github.com/marpiech/largedatablog.git -b thrift thrift-and-java

Problems:

How to get rid of ugly warnings caused by autogenerated thrift code? (in Eclipse)
Create new source directory: e.g. src/thrift. Copy autogenerated code to the new directory. Then, Right click on the directory -> Build Path -> Use as Source Folder. Right click again -> Build Path -> Configure Build Path... -> Ignore optional compile problems -> Toggle.

org.apache.thrift.TApplicationException: [your method] failed: unknown result
your server implementation returned null or see: http://stackoverflow.com/questions/4244350/how-thread-safe-is-thrift-re-i-seem-to-have-requests-disrupting-one-another

TNonblockingServer.java [line number] Read an invalid frame size of [integer number]. Are you using TFramedTransport on the client side?
Wrap your TSocket into TFramedTransport (i.e. new TFramedTransport(new TSocket("localhost", 9090)))

czwartek, 13 grudnia 2012

Spring examples #2 - Testing Controller using Spring MVC with session scope

Sometimes there is need to store user session data in a session object. There are two choices for that. We can add session scope to a specific object or to whole controller. For testing purposes it is easier (however, not better) to choose the second option. Let us add some annotations to controller:
@Controller
@Scope("session")
public class MyController {

 @Autowired
 SomeSingletonFromContext singleton;

 SessionObject sessionObject = new SessionObject();

 @RequestMaping("/my.htm")
 public void myRequest(HttpServletRequest, HttpServletResponse) {
  ServletOutputStream out = response.getOutputStream();
  response.setContentType("application/json");
  response.setHeader("Cache-Control", "no-cache");
  out.print("Hello Session User");
 }
}
In the tricky part we will enable session for testing. The context configuartion below is our "access point" for controller testing class. Note the 'import' tag pointing to default servlet configuration.



  
      
          
              
                  
              
          
      
  

  


In the servlet-context we need to scan for controller:



Finally we have to set up our test:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({
 "file:path/to/test-context-as-above.xml"})
public class MyControllerTest {
 
    private MockHttpServletRequest request;
    private MockHttpServletResponse response;
    
    @Autowired
    private MyController myController;
 
    @Before
    public void setUp() {
     request = new MockHttpServletRequest();
        response = new MockHttpServletResponse();        
    }

    @Test
    public void testSubmit() throws Exception {

     request.setMethod("POST");
        request.setRequestURI("/my.htm");
        request.addParameter("param", "value");
        
        @SuppressWarnings("unused")
        final ModelAndView mavBack = new AnnotationMethodHandlerAdapter()
            .handle(request, response, controller);
        
        assertEquals(response.getContentType(), "application/json");

    }
}
That's all.

środa, 25 lipca 2012

Ohloh code

When I heard that Google Code Search is going to be closed i started to look for it's alternative. I used it on a routine basis - looking for spring solutions, gwt tricks or some xml hibernate configurations.

The best alternative was koders.com, but it was lacking some features - for example searching in xml language(!).

Now, the Koders project is merging with Ohloh in the form of code.ohloh.net. The Ohloh code is great. I can look for gwt examples, spring xml configuration files or hibernate tricks. The left panel is perfect. The code preview is optimal for me. A look of the tool is clean and nice.

poniedziałek, 23 lipca 2012

Installing latest R version under Ubuntu

Ubuntu does not come with the recent R version. Below is the solution. Mind that you can choose different cran mirror. I use wroclaw/poland cran mirror to do this. My Ubuntu version is 11.10 -> oneiric. Keep in mind that. For 12.04 you should use -> precise
sudo apt-get install python-software-properties
sudo add-apt-repository "http://r.meteo.uni.wroc.pl/bin/linux/ubuntu oneiric/"
sudo apt-get update
You will get: W: GPG error: http://r.meteo.uni.wroc.pl oneiric/ Release: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY 51716619E084DAB9
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 51716619E084DAB9
sudo apt-get install r-base-dev 
And we are done.

wtorek, 17 lipca 2012

Spring examples #1 - beginning with spring


I decided to prepare for Spring certification. Therefore, in the series of 'Spring examples' posts I will introduce and clean up the most important Spring concepts.

The source code for this post is available at:
git clone git@bitbucket.org:marpiech/iseqspringcore.git

Prerequisities:
- eclipse: download 'Eclipse IDE for Java EE Developers' from http://www.eclipse.org/downloads/
- maven: download it from http://maven.apache.org/download.html or by sudo apt-get install maven2 
- m2eclipse: in eclipse Help -> Marketplace -> Maven integration for Eclipse -> install
- SpringSource Tool Suite: in eclipse Help -> Marketplace -> STS -> install

First, we have to create directory structure. bash
mkdir iseqspringcore
cd iseqspringcore
mkdir -p src/{test,main}/{java,resources}
Next, we need to set up maven.
nano pom.xml
and paste:


 4.0.0

 com.intelliseq
 spring-tutorial
 1.0

 Spring Tutorial Part 1
Now, we have to prepare eclipse project. bash
mvn install
mvn eclipse:eclipse

Let's switch to eclipse.
File -> Import -> General -> Existing Projects into workspace
RightClick on Project -> Configure -> Convert to maven project

Add maven repository to pom.xml

 
       central
       Maven Repository Switchboard
       default
       http://repo1.maven.org/maven2
       
         false
       
   

RightClick on Project -> Maven -> Add Dependency -> org.springframework, spring-context
Have a look at pom.xml and in project at Maven Dependencies set of libraries.

In src/main/java create package com.intelliseq.springexamples.core Create application-context.xml in the com.intelliseq.springexamples package. There are two two types of bean instantiation through setters: classic one and modern one (see below).


 
  
  
 

 

 
  
 
Let's create Person class in the com.intelliseq.springexamples.core package.
package com.intelliseq.springexamples.core;

public class Person {
 
 private String firstName;
 private String familyName;
 
 public void setFirstName(String firstName) {
  this.firstName = firstName;
 }

 public void setFamilyName(String familyName) {
  this.familyName = familyName;
 }

 @Override
 public String toString() {
  return firstName + " " + familyName;
 }
}
And finally let's create application runner class SpringApp in the com.intelliseq.springexamples.core package. The SpringApp class uses application-context through ClassPathXmlApplicationContext class.
package com.intelliseq.springexamples.core;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SpringApp {

 public static void main (String[] args) {
  ApplicationContext context =
       new ClassPathXmlApplicationContext(new String[] {"com/intelliseq/springexamples/application-context.xml"});
  Person person = (Person) context.getBean("person");
  System.out.println(person);
  Person modernPerson = (Person) context.getBean("person-modern");
  System.out.println(modernPerson);
 }
 
}
Run Spring App and voila.

środa, 13 czerwca 2012

Getting linked exons BED from UCSC tables

Today I needed bigBed file for visualization of transcript positions in a browser which is bigBed and bigWig based. I have found a discussion where Katrina Learned from UCSC Genome Bioinformatics Group posted very usefull script. I am not going to reinvent the wheel.
nano genePredToBed
and paste this
#!/usr/bin/awk -f

#
# Convert genePred file to a bed file (on stdout)
#
BEGIN {
     FS="\t";
     OFS="\t";
}
{
     name=$1
     chrom=$2
     strand=$3
     start=$4
     end=$5
     cdsStart=$6
     cdsEnd=$7
     blkCnt=$8

     delete starts
     split($9, starts, ",");
     delete ends
     split($10, ends, ",");
     blkStarts=""
     blkSizes=""
     for (i = 1; i <= blkCnt; i++) {
         blkSizes = blkSizes (ends[i]-starts[i]) ",";
         blkStarts = blkStarts (starts[i]-start) ",";
     }

     print chrom, start, end, name, 1000, strand, cdsStart, cdsEnd, 0, 
blkCnt, blkSizes, blkStarts
}
We are almost ready to make our bed file:
chmod +x genePredToBed
wget http://hgdownload.cse.ucsc.edu/goldenPath/mm9/database/knownGene.txt.gz
gzip -d knownGene.txt.gz
cat knownGene.txt | ./genePredToBed > known.bed
Now we can use Jim Kent's bedToBigBed and we are done.

Getting GTF from UCSC with proper gene_id

While downloading GTF file (knownGenes or ensemblGenes) from UCSC Table browser an output has one serious issue. Transcript_id = gene_id. And in fact there is no gene_id. Below simple solution is presented for this problem (mm9 genome):

#prerequisities mysql
wget http://hgdownload.cse.ucsc.edu/admin/exe/linux.x86_64/genePredToGtf
chmod +x genePredToGtf
sudo ln -s ./genePredToGtf genePredToGtf
mysql --user=genome --host=genome-mysql.cse.ucsc.edu -A -N -e "select * from ensGene;" mm9 | cut -f2- | genePredToGtf file stdin ensGene.gtf

wtorek, 1 maja 2012

Converting between .gff, .gtf and .bed formats

Various NGS analysis tools require various input formats. It is sometimes tricky to make free software working.
Recently, all required tools for converting between .gff, .gtf and .bed formats were incorporated into Tubingen Rätsch Lab Galaxy instance

http://galaxy.tuebingen.mpg.de/

czwartek, 26 kwietnia 2012

R tips

If you are looking for R tips for beginners and advanced users there is nothing better than this:
http://pj.freefaculty.org/R/Rtips.html

or in .pdf version:
http://pj.freefaculty.org/R/Rtips.pdf

Topics include:
- exchange data between R and other programs (Excel, etc)
- create variable names on the fly
- return multiple values from a function
- scatterplot: smooth a line connecting points
- test for Normality
- multiple analysis of variance
- character encoding
- R environment in side scripts

and many more. Enjoy.

poniedziałek, 12 marca 2012

[solved] git updating directory error

Today, my collaborator in a project replaced webapp/gwt/ directory with dynamic link to war/gwt directory

In .gitignore we had only this statement:
...
webapp/gwt/* 
...

During the pull origin somebranch i got this error:
git error: Updating the following directories would lose untracked files in it:
{{yourdir}}

Solution:
rm -rf {{yourdir}}
git pull origin {{somebranch}}
and add to .gitignore the conflicting dynamic link.

Google wasn't very helpfull this time. I hope this tip will help someone in the future...

poniedziałek, 5 marca 2012

[solved] libexpat.la missing

Today I got this error:

libtool: link: cannot find the library "libexpat.la" or unhandled argument libexpat.la ubuntu

To solve this issue run in apache source directory

cd srclib/apr-util/xml/expat
./configure
# OR ./configure --prefix=/{{YOURDIR}}/apache/source/httpd-2.2.22/srclib/apr-util/xml/expat/
sudo make install
# OR make install

Remember to clean up your previous apache install after make install failed

cd {{YOURDIR}}/apache/
ls -la
rm -r bin
rm -r build
rm -r include
rm -r lib

czwartek, 23 lutego 2012

10 papers that every bioinformatician should read

This list of top 10 papers in bioinformatics does not only consist of purely bioinformatic papers, but shows how gentle and simple bioinformatics can and should be:

1. Dudley JT, Butte AJ (2009) A Quick Guide for Developing Effective Bioinformatics Programming Skills. PLoS Computational Biology 5(12)
Link
"Consequently it is no surprise that many successful bioinformatics apps are written by biologists who lack formal computer science training, as they undoubtedly put scientific utility ahead of architectural elegance and completeness."

2. Kim TK, Hemberg M, Gray JM, Costa AM, Bear DM, Wu J, Harmin DA, Laptewicz M, Barbara-Haley K, Kuersten S, Markenscoff-Papadimitriou E, Kuhl D, Bito H, Worley PF, Kreiman G, Greenberg ME (2010) Widespread transcription at neuronal activity-regulated enhancers. Nature 465(7295)
Link
Simple and brilliant use of ChIP-seq and RNA-seq techniques.

3. Goecks J, Nekrutenko A, Taylor J, and The Galaxy Team (2010) Galaxy: a comprehensive approach for supporting accessible, reproducible, and transparent computational research in the life sciences. Genome Biology 11(8)
Link
Bioinformatics for the masses.

4. Ameur A, Zaghlool A, Halvardson J, Wetterbom A, Gyllensten U, Cavelier L, Feuk L (2011) Total RNA sequencing reveals nascent transcription and widespread co-transcriptional splicing in the human brain. Nature Structural & Molecular Biology 18
Link
Great example of getting additional features from RNA-seq data.

5. Smedley D, Haider S, Ballester B, Holland R, London D, Thorisson G, Kasprzyk A (2009) BioMart – biological queries made easy. BMC Genomics 10
Link
Data mart for biologists.

6. Krzywinski M, Schein J, Birol I, Jones S, Marra M (2008) Circos - an information aesthetic for comparative genomics. Genome Informatics conference
Link
Beauty of data visualization.

7. Majewski J, Ott J (2004) Distribution and characterization of regulatory elements in the human genome. Genome Research 12
Link
One of the first successful attempts to analyze genomic features at genome scale.

8. Kent WJ, Zweig AS,  Barber G, Hinrichs AS, Karolchik D (2009) BigWig and BigBed: enabling browsing of large distributed datasets. Bioinformatics 26(17)
Link
Standard formats for storing NGS-data. Fast, simple.


The list will continue...

piątek, 20 stycznia 2012

Run process as another user in init.d script

start-stop-daemon --start --quiet --chuid $USER:$GROUP --exec $SCRIPT

Installing Cassandra on Ubuntu server

# enable add-apt-repository
sudo apt-get install python-software-properties
# add repository for java
sudo add-apt-repository ppa:ferramroberto/java
# update
sudo apt-get update
# install Sun (I hate Oracle) java
sudo apt-get install sun-java6-jdk sun-java6-plugin
# create directory for installation
sudo mkdir /opt/cassandra
# add cassandra user [set password]
sudo adduser cassandra
# change owner of istallation directory
sudo chown cassandra:cassandra /opt/cassandra/
# switch to cassandra user
su -l cassandra
# go to installation directory
cd /opt/cassandra
# download latest version (check address on cassandra.apache.org)
wget http://www.apache.net.pl//cassandra/1.0.7/apache-cassandra-1.0.7-bin.tar.gz
# untar
tar xvzf apache-cassandra-1.0.7-bin.tar.gz
# back to admin account, create cassandra var directory
logout
sudo mkdir /var/lib/cassandra/
sudo chown cassandra:cassandra /var/lib/cassandra/
sudo mkdir /var/log/cassandra/
sudo chown cassandra:cassandra /var/log/cassandra/
# switch again to cassandra user
su -l cassandra
mkdir /var/lib/cassandra/data
mkdir /var/lib/cassandra/commitlog
mkdir /var/lib/cassandra/saved_caches
Add to /etc/init.d/cassandra
start-stop-daemon --start --quiet --chuid cassandra:cassandra --exec /opt/cassandra/apache-cassandra-1.0.7/bin/cassandra

czwartek, 3 listopada 2011

Installing Java6 JDK on Ubuntu 11.10

sudo add-apt-repository ppa:ferramroberto/java
sudo apt-get update
sudo apt-get install sun-java6-jdk sun-java6-plugin

niedziela, 31 lipca 2011

Initialization of github repository

sudo apt-get install git-core git-gui git-doc
ssh -T git@github.com
git config --global user.name "John Doe"
git config --global user.email "doe.john@gmail.com"
git config --global github.user jodoe
git config --global github.token 12345yourtokenabcdef
git init
git add .
git commit -m 'Initial commit'
git remote add origin git@github.com:jodoe/jodoeproject.git
git push -u origin master

[solved] Cassandra TApplicationError type: 6

Today I have got strange error while using cassandra:

me.prettyprint.hector.api.exceptions.HCassandraInternalException:
Cassandra encountered an internal error processing this request:
TApplicationError type: 6 message:Internal error processing
batch_mutate

It was because I am using OrderPreservingPartitioner with IntegerType as key validator.
Trying to insert key over 127 gives above error.
This partitioner sholud be used with one of String types (e.g. utf8).

Sollution: ByteOrderedPartitioner.

środa, 6 lipca 2011

[solved] Missing artifact hector-core

Another trap...

While trying to add hector-core dependency through the m2eclipse I got this error:

Missing artifact me.prettyprint:hector-core:bundle:0.8.0-1:compile

Hint: this is not a bundle...

40 minutes is lost...

wtorek, 5 lipca 2011

Plotting ROC curves in ggplot2

Default ROC curves in R are disgusting. ggplot2 comes to the rescue.


First, let's write some data generating function that will be useful for ROC:
getExampleDataForROC <- function(len = 100, distort = 1) {
  half <- round(len/2)
  ### Group ###
  group <- vector()
  group[1:half] <- "Disease"
  group[(half + 1):len] <- "Control"
  group <- as.factor(group)
  ### Score ###
  score <- vector()
  score[1:half] <- 1
  score[(half + 1):len] <- -1
  for (i in 1:len)
    score[i] <- score[i] + rnorm(1, 0, distort)
  order <- order(score)
  data.frame(pos = score[order], group = group[order])
}

Let's write ROC plotting functions:
getPointsForROC <- function(len = 100, distort = 1) {
  basal <- getExampleDataForROC(len, distort)
  tp <- vector(); tn <-vector(); fp <-vector(); fn <- vector()
  tpr <- vector(); fpr <- vector()
  acc <- vector(); spc <- vector()
  len <- dim(basal)[1]
  for(i in 1:len-1) {
    tp[i] <- sum(basal[(i+1):len,2] == "Disease")
    tn[i] <- sum(basal[1:i,2] == "Control")
    fp[i] <- sum(basal[(i+1):len,2] == "Control")
    fn[i] <- sum(basal[1:i,2] == "Disease")
    tpr[i] <- tp[i] / (tp[i] + fn[i])
    fpr[i] <- fp[i] / (fp[i] + tn[i])
    acc[i] <- (tp[i] + tn[i]) / ((tp[i] + fn[i]) +  (fp[i] + tn[i]))
    spc[i] <- 1 - fpr[i]
  }
  points <- (cbind(fpr,tpr))[(len-1):1,]
  points <- rbind(points, c(1,1))
  return(points)
} 


plotROC <- function(len = 100) {
  points.part1 <- getPointsForROC(len, 1)
  desc.part1 <- rep("Distort = 1",len)
  points.part2 <- getPointsForROC(len, 1.5)
  desc.part2 <- rep("Distort = 1.5",len)
  points.part3 <- getPointsForROC(len, 2)
  desc.part3 <- rep("Distort = 2",len)
  points.part4 <- getPointsForROC(len, 2.5)
  desc.part4 <- rep("Distort = 2.5",len)

  points <- rbind(points.part1, points.part2, points.part3, points.part4)
  desc <- c(desc.part1, desc.part2, desc.part3, desc.part4)
  data <- data.frame(TPR = points[,2], FPR = points[,1], GeneSet = desc)
  colors = brewer.pal(5, "YlOrRd")[2:5]
  qplot(FPR, TPR, data = data, geom = "blank", main = "ROC curve", xlab = "False Positive Rate (1-Specificity)", ylab = "True Positive Rate (Sensitivity)" ) + geom_line(aes(x = FPR, y = TPR, data = data, colour = GeneSet), size = 2, alpha = 0.7) + scale_colour_manual(values=colors)
}
Finally, let's generate plot:
plotROC(1000)

poniedziałek, 4 lipca 2011

Plotting PCA results in ggplot2

Default PCA plots in R are disgusting. ggplot2 comes to the rescue.


First, let's write some data generating functions that will be useful for PCA:
getVector <- function(n = 20, dims = 2) {
  out <- vector()
  breaks <- round((n/dims)*(1:dims))
  start <- 1  
  for(i in 1:dims) {
    num <- rnorm(1, 10, 1)
    for(j in start:(breaks[i])) {
      out[j] <- num + rnorm(1, 0, 0.2)
    }
    start <- breaks[i] + 1
  } 
  out
}

getData <- function(rows = 10, cols = 20, groups = 2, dims = 2, distort = 0.5) {
  out <- matrix(data = 10, nrow = rows, ncol = cols)
  ### make groups ###
  breaks <- round((rows/groups)*(1:groups))
  start <- 1  
  for(i in 1:groups) {
      vector <- getVector(n = cols, dim = 2)
    for(j in start:(breaks[i])) {
      out[j,] <- vector
    }
    start <- breaks[i] + 1
  }
  ### make error ###
  for(i in 1:rows) {
    out[i,] <- out[i,] + rnorm(n = cols, mean = 0, sd = distort)
  }
  ### return ###
  rownames(out) <- paste("Row ", 1:rows, sep = "")
  colnames(out) <- paste("Col ", 1:cols, sep = "")
  out
}

getGroup <- function(rows = 10, groups = 2) {
  out <- vector()
  breaks <- round((rows/groups)*(1:groups))
  start <- 1  
  for(i in 1:groups) {
    for(j in start:(breaks[i])) {
      out[j] <- i
    }
    start <- breaks[i] + 1
  }
  out <- as.factor(out)
  out
}

Let's write PCA plotting function:
makePcaPlot <- function(x = getData(), group = getGroup(), title = "") {
  require(ggplot2)
  require(RColorBrewer)
  data <- x
  data <- t(apply(data, 1, scale))
  rownames(data) <- rownames(x)
  colnames(data) <- colnames(x)
  mydata <- t(data)  
  groupFactor <- group
  mydata.pca <- prcomp(mydata, retx=TRUE, center=TRUE, scale.=TRUE)  

  percent <- round((((mydata.pca$sdev)^2 / sum(mydata.pca$sdev^2))*100)[1:2])
  loadings <- mydata.pca$rotation
  rownames(loadings) <- colnames(mydata)
  scores <- mydata.pca$x
  cex = 3
  group <- as.character(groupFactor)
  what <- groupFactor == "1"; group[what] <- "One"
  what <- groupFactor == "2"; group[what] <- "Two"
  group <- factor(group)
  group <- factor(group, levels=c("Two", "One"), ordered=TRUE)
  colors = sample(1:11, size = length(levels(group)))


  PCA1 <- scores[,1]
  PCA2 <- scores[,2]
  base_size = 10

  qplot(PCA2, PCA1, geom="blank", main = title, xlab = paste("PCA2 (", percent[2], "%)", sep = ""), ylab = paste("PCA1 (", percent[1], "%)", sep = "")) + geom_point(aes(colour = group), size = 6, alpha = 3/4) + scale_colour_manual(values=brewer.pal(11, "RdYlGn")[11:1][colors]) + opts(
      axis.text.x = theme_text(size = base_size * 1.3 , lineheight = 0.9, colour = "grey50", hjust = 1, angle = 90),
      axis.text.y =       theme_text(size = base_size * 1.3, lineheight = 0.9, colour = "grey50", hjust = 1)
      )
}
Finally, let's generate plot:
makePcaPlot(getData(30,4,2,distort = 0.7), getGroup(30,2))