Chromosomes colored by synteny



#include "visual/Whiteboard.h"

#include "base/CommandLineParser.h"
#include "base/FileParser.h"
#include "base/SVector.h"
#include "visual/Color.h"

#include "visual/Axes.h"

// Define a chromosome
class Chr
{
public:
  Chr() {
    m_y = 0.;  
    m_len = 0;
    m_width = 10.;
  }

  Chr(double y, double l, const string &c, double w, color col) {
    m_y = y;
    m_name = c;
    m_len = l;
    m_width = w;
    m_color = col;
  }

  void Set(double y, double l, const string &c, double w = 10.) {
    m_y = y;
    m_name = c;
    m_len = l;
    m_width = w;
  }

  

  const string & Name() const {return m_name;}
  color Color() const {return m_color;}
  
  void DrawFill(ns_whiteboard::whiteboard & board, double scale, double x_offset, double from, double to, color col) {
    //cout << "Filling." << endl;
    board.Add( new ns_whiteboard::rect( ns_whiteboard::xy_coords(x_offset + from/scale, m_y + m_width ), 
                                        ns_whiteboard::xy_coords(x_offset + to/scale, m_y),
                                        col) );

  }

  double DrawBorder(ns_whiteboard::whiteboard & board, double scale, double x_offset) {
    double w = 1.;
    board.Add( new ns_whiteboard::rect( ns_whiteboard::xy_coords(x_offset-w, m_y + m_width + w), 
                                        ns_whiteboard::xy_coords(x_offset + m_len/scale+w, m_y - w),
                                        color(0, 0, 0)) );
    board.Add( new ns_whiteboard::rect( ns_whiteboard::xy_coords(x_offset, m_y + m_width), 
                                        ns_whiteboard::xy_coords(x_offset + m_len/scale, m_y),
                                        color(0.99, 0.99, 0.99)) );
    
    board.Add( new ns_whiteboard::text( ns_whiteboard::xy_coords(x_offset + m_len/scale + 8, m_y + m_width/2),
					m_name, color(0,0,0), 8., "Times-Roman", 0, true));
 
    
    double shift = 13;
    board.Add( new ns_whiteboard::rect( ns_whiteboard::xy_coords(x_offset-w-1.5*m_width-shift, m_y + m_width + w), 
					ns_whiteboard::xy_coords(x_offset+w-1.5*m_width-shift + m_width, m_y - w),
					color(0, 0, 0)) );
    board.Add( new ns_whiteboard::rect( ns_whiteboard::xy_coords(x_offset-1.5*m_width-shift, m_y + m_width), 
					ns_whiteboard::xy_coords(x_offset-1.5*m_width-shift + m_width, m_y),
					m_color) );

   return x_offset + m_len/scale;

  }

private:
  double m_y;
  double m_len;
  string m_name;
  double m_width;

  color m_color;
  
};

// Use the whiteboard's color palette
color GetColor(int i) 
{
  
  return MakeUpColor(i);

}

// Read the header of a Satsuma/Mizbee file
double ReadHeader(string & name, svec<Chr> &chr, FlatFileParser & parser, double off)
{
  // Set up chromosome structures
  while(parser.ParseLine()) {
    if (parser.GetItemCount() == 0)
      continue;
    if (parser.GetItemCount() == 2 && parser.AsString(0) == "genome") {
      name == parser.AsString(1);
      continue;
    }
    if (parser.GetItemCount() == 2 && parser.AsString(0) == "chromosomes") {
      int n = parser.AsInt(1);
      for (int i=0; i<n; i++) {
	parser.ParseLine();
	chr.push_back(Chr(off, parser.AsFloat(1), parser.AsString(0), 10., GetColor(i)));
	off += 14.;
      }
      return off;
    }
  }

  return off;
}
 

int FindChr(const svec<Chr> & c, const string & name) 
{
  for (int i=0; i<c.isize(); i++) {
    if (c[i].Name() == name)
      return i;
  }
  
  return -1;
}
 
int main( int argc, char** argv )
{
 
  commandArg<string> aStringI1("-i","MizBee file");
  commandArg<string> aStringO("-o","outfile (post-script)");
  commandArg<double> dotSize("-d","dot size", 1.);
  commandArg<double> aScale("-s","scale", 60000.);
  commandArg<int> cTarget("-t","target id", -1);
  commandArg<bool> bF("-f","forward only", 0);

  
  commandLineParser P(argc,argv);
  P.SetDescription("Comparative cromosome painter");

  P.registerArg(aStringI1);
  P.registerArg(aStringO);
  P.registerArg(dotSize);
  P.registerArg(aScale);
  P.registerArg(cTarget);
  P.registerArg(bF);

  P.parse();

  string i1 = P.GetStringValueFor(aStringI1);
  string o = P.GetStringValueFor(aStringO);
  double dd = P.GetDoubleValueFor(dotSize);
  int targetID = P.GetIntValueFor(cTarget);
  bool fwOnly = P.GetBoolValueFor(bF);


  int i, j;

  
  ns_whiteboard::whiteboard board;

  int x_offset = 100;
  int y_offset = 100;

  double scale = P.GetDoubleValueFor(aScale);
  double x_scale = scale;
  double x_max = 0;
  double y_max = 0;

  FlatFileParser parser;

  parser.Open(i1);
  
  svec<Chr> target;
  svec<Chr> query;

  string name1, name2;
  double d = ReadHeader(name1, target, parser, x_offset);

  d = ReadHeader(name2, query, parser, d + 20.);
  
  y_max = d;

  for (i=0; i<target.isize(); i++) {
    d = target[i].DrawBorder(board, scale, x_offset);
    if (d > x_max)
      x_max = d;
  }
  for (i=0; i<query.isize(); i++) {
    d = query[i].DrawBorder(board, scale, x_offset);
    if (d > x_max)
      x_max = d;
  }
  

  cout << "Target chr: " << target.isize() << endl;
  cout << "Query chr: " << query.isize() << endl;

  //parser.ParseLine();
  while(parser.ParseLine()) {
    if (parser.GetItemCount() < 10)
      continue;

    const string & nT = parser.AsString(0);
    const string & nQ = parser.AsString(4);
	
    int fromT = parser.AsInt(1); 
    int toT = parser.AsInt(2); 
    int fromQ = parser.AsInt(5); 
    int toQ = parser.AsInt(6); 

    int iT = FindChr(target, nT);
    int iQ = FindChr(query, nQ);
    
    // Fill in the regions
    target[iT].DrawFill(board, scale, x_offset, fromT, toT,  query[iQ].Color());
    query[iQ].DrawFill(board, scale, x_offset, fromQ, toQ,  target[iT].Color());

  }

  ofstream out (o.c_str());
  ns_whiteboard::ps_display display(out, x_max + x_offset, y_max + x_offset);
  board.DisplayOn(&display);
 
 
  return 0;
}


Result:
Result