Processing – DNA Surface Generator
Posted By: Jordan ParsonsWell this is another processing project. I started with 01hgp10.txt. Which is a snippet of the first human chromosome from Human Genome Project at Project Gutenberg. I wanted to create a system in which I could analyze the number of individual markers (G, C, T, and A) and see how many of them there were per line of code. With these total then I assigned each letter a multiplier or value which allows me to control its value, or height off the Z axis. So the process goes like this.

1. Read line one of the file and parse each character into an array.
2. Parse the array.
3A. If the letter is “G” add one to nG. (Number of G’s, which starts at 0).
3B. If the letter is “C” add one to nC. (Number of C’s, which starts at 0).
3C. If the letter is “T” add one to nT. (Number of T’s, which starts at 0).
3D. If the letter is “A” add one to nA. (Number of A’s, which starts at 0).
4A. Multiply nG by the Value for G (Value_G). Which is equal to vG.
4A. Multiply nC by the Value for C (Value_C). Which is equal to vC.
4A. Multiply nT by the Value for T (Value_T). Which is equal to vT.
4A. Multiply nA by the Value for A (Value_A). Which is equal to vA.
5. Add vG, vC, vT, vA and use the resultant as the Z coordinate for the first grid point.
6. Advance to the next grid point and loop.
The values of G, C, T, and A; the grid spacing; the grid size in both X and Y are all controlled by sliders so that I can see the effects in real time (The sliders are in the controlP5 library, http://www.sojamo.de/libraries/controlP5/). Also processing will export the surface as lines to a .dxf file when the r key is pressed.
I’m fairly happy with this project, its the first version which is always a little buggy. As it stands now when the grid X or Y size is an odd number the program goes haywire and the surface twitches and shows multiple layers and strange ghost images. Also when exported and when shown in processing the surface looks like it was contoured in the X direction, so it has to be lofted to be treated as 3D, which looses some of the data. Right now its an experiment for me, and as a first attempt I am quite happy. The source code is below, if anyone can fix my bugs or offer ideas please feel free to do so.
Source:
//-------------------------------
//DNA Surface Generator V1
//© 2009 Jordan Parsons
//Creative Commons Attribution-Share Alike 3.0
//www.jordanparsons.com
//--------------------------------
import processing.dxf.*;
import processing.opengl.*;
import controlP5.*;
ControlP5 controlP5;
//Variable Mess
int wSize=500;
int nA;
int nC;
int nG;
int nT;
int gA;
int gC;
int gG;
int gT;
String fileToOpen = "01hgp10.txt";
int[] aA = new int[9999];
int[] aC = new int[9999];
int[] aG = new int[9999];
int[] aT = new int[9999];
int n = 0;
int nTotal = 0;
public float A_Value=.5;
public float C_Value=.5;
public float G_Value=.5;
public float T_Value=.5;
//grid size
int gSpace = 100;
int gX = 10;
int gY = 10;
int gXSp = 10;
int gYSp = 10;
int gArea = gX*gY;
int gStartX = 0;
int gStartY = 0;
int gStartXk = 0;
int gStartYk = 0;
public int Spacing=10;
public int X_Width=10;
public int Y_Width=10;
int letter=1;
int escape;
int beginRec=0;
int counter=0;
//Go
void setup(){
background(100);
size(500,500,OPENGL);
controlP5 = new ControlP5(this);
//Slider info------name&var min max start x y width height
controlP5.addSlider("Spacing",5,250,10,5,395,100,10);
controlP5.addSlider("X_Width",2,20,10,5,410,100,10);
controlP5.addSlider("Y_Width",2,20,10,5,425,100,10);
controlP5.addSlider("A_Value",0,2,.5,5,440,100,10);
controlP5.addSlider("C_Value",0,2,.5,5,455,100,10);
controlP5.addSlider("G_Value",0,2,.5,5,470,100,10);
controlP5.addSlider("T_Value",0,2,.5,5,485,100,10);
//get the data...*/
surf_data();
surf_draw();
}
void draw(){
gXSp=Spacing;
gYSp=Spacing;
gX=X_Width;
gY=Y_Width;
surf_draw();
}
void surf_draw(){
if(beginRec==1){
// beginRaw(DXF, "output.dxf");
}
background(100);
pushMatrix();
translate((width/2-100),(height/2-100));
rotateX(radians(60));
noFill();
stroke(0, 0, 0);
beginShape();
for(n=0; n < (gX*gY); n++){
switch(letter){
case 1:
curveVertex(gStartX,gStartY,((aA[n]*A_Value)));
letter=letter+1;
break;
case 2:
curveVertex(gStartX,gStartY,((aC[n]*C_Value)));
letter=letter+1;
break;
case 3:
curveVertex(gStartX,gStartY,((aG[n]*G_Value)));
letter=letter+1;
break;
case 4:
curveVertex(gStartX,gStartY,((aT[n]*T_Value)));
letter=1;
break;
}
//println(gStartX+" "+gStartY+" "+((aA[n]*A_Value))+" "+counter+". \n");
gStartX=gStartX+gXSp;
counter = counter+1;
if(counter == gX){
counter = 0;
gStartY=gStartY+gYSp;
gStartX=gStartXk;
endShape();
//println("end shape");
beginShape();
}
}
gStartX=gStartXk;
gStartY=gStartYk;
//endRaw();
popMatrix();
// return;
if(beginRec==1){
// endRaw();
beginRec=0;
}
}
void surf_data(){
String lines[] = loadStrings(fileToOpen);
println("there are " + lines.length + " lines");
escape=lines.length;
for (int i=1; i < lines.length; i++) {
String strFor = lines[i];
strFor = strFor.toUpperCase();
n=0;
nTotal=0;
for (int n=0; n < strFor.length(); n++){
char charCheck = strFor.charAt(n);
switch(charCheck) {
case 'A':
nA=nA+1;
break;
case 'T':
nT=nT+1;
break;
case 'C':
nC=nC+1;
break;
case 'G':
nG=nG+1;
break;
}
//println(charCheck+" "+n);
}
nTotal=nA+nT+nC+nG;
/*println(lines[i]
+ " Contains " +nA+" A's."
+ " Contains " +nT+" T's."
+ " Contains " +nG+" G's."
+ " Contains " +nC+" C's."
);*/
aA[i] = nA;
aC[i] = nC;
aT[i] = nT;
aG[i] = nG;
// println(aA[1]);
nA=0;
nT=0;
nG=0;
nC=0;
}
}
void keyPressed(){
if(key == 'r'){
beginRec=1;
}
}
No Comments »
No comments yet.
RSS feed for comments on this post. TrackBack URL











