using namespace std;
-PathScene::PathScene(Mussa* analysis, QWidget *parent) :
- QGLWidget(parent),
- viewport_height(0),
- viewport_width(0),
- clipZ(30.0),
- zoom(2),
- maxOrtho2d(-50.0, -50, 3000000.0, 300.0),
- curOrtho2d(maxOrtho2d),
- viewport_center(((curOrtho2d.right()-curOrtho2d.left())/2)+curOrtho2d.left()),
- selectedMode(false),
- rubberBand(0),
- drawingBand(false)
+PathScene::PathScene(QWidget *parent)
+ : QGLWidget(parent)
+ //selectedMode(false),
+ //rubberBand(0),
+ //drawingBand(false)
{
- if (analysis == 0)
- {
- mussaAnalysis = new Mussa;
- }
- else
- {
- mussaAnalysis = analysis;
- }
- updateScene();
}
QSize PathScene::sizeHint() const
{
- return QSize(400, 400);
-}
-
-float PathScene::left()
-{
- return maxOrtho2d.left();
-}
-
-float PathScene::right()
-{
- return maxOrtho2d.right();
-}
-
-float PathScene::viewportLeft()
-{
- return curOrtho2d.left();
-}
-
-float PathScene::viewportRight()
-{
- return curOrtho2d.right();
+ return QSize(GlTracks::viewportHeight(), GlTracks::viewportWidth());
}
-float PathScene::viewportCenter()
+void PathScene::setViewportCenter(float x)
{
- return viewport_center;
-}
+ const float epsilon = 1e-10;
+ float center = fabs(GlTracks::viewportCenter());
+ float abs_x = fabsf(x);
+ float difference = fabsf(abs_x - center);
-void PathScene::updateViewport(float center, int new_zoom)
-{
- float max_width = maxOrtho2d.width();
- if (new_zoom < 1) new_zoom = 1;
- float new_max_width = max_width / new_zoom;
- //curOrtho2d.setLeft(max(center-new_max_width, maxOrtho2d.left()));
- //curOrtho2d.setRight(min(center+new_max_width, maxOrtho2d.right()));
- curOrtho2d.setLeft(center-new_max_width);
- curOrtho2d.setRight(center+new_max_width);
- emit viewportChanged();
-}
-
-void PathScene::setViewportX(float x)
-{
//hopefully this calculates a sufficiently reasonable == for a float
- if (x != viewport_center )
+ if (difference < epsilon * abs_x or difference < epsilon * center)
{
- updateViewport(x, zoom);
- viewport_center = x;
+ GlTracks::setViewportCenter(x);
update();
}
}
void PathScene::setZoom(int new_zoom)
{
- if (zoom != new_zoom) {
- // try to figure out where we should be now?
- updateViewport(viewport_center, new_zoom);
- zoom = new_zoom;
+ if (new_zoom != GlTracks::zoom()) {
+ GlTracks::setZoom(new_zoom);
update();
}
}
-void PathScene::setClipPlane(int newZ)
+void PathScene::setClipPlane(int )
{
+/*
if (clipZ != (double) newZ){
clipZ = (double) newZ;
update();
}
-}
-
-void PathScene::loadMotifList()
-{
- QString caption("Load a motif list");
- QString filter("Motif list(*.txt *.mtl)");
- QString path = QFileDialog::getOpenFileName(this,
- caption,
- QDir::currentPath(),
- filter);
- // user hit cancel?
- if (path.isNull())
- return;
- // try to load safely
- try {
- mussaAnalysis->load_motifs(path.toStdString());
- updateScene();
- } catch (runtime_error e) {
- QString msg("Unable to load ");
- msg += path;
- msg += "\n";
- msg += e.what();
- QMessageBox::warning(this, "Load Motifs", msg);
- }
- assert (mussaAnalysis != 0);
-}
-void PathScene::loadMupa()
-{
- QString caption("Load a mussa parameter file");
- QString filter("Mussa Parameters (*.mupa)");
- QString mupa_path = QFileDialog::getOpenFileName(this,
- caption,
- QDir::currentPath(),
- filter);
- // user hit cancel?
- if (mupa_path.isNull())
- return;
- // try to load safely
- try {
- Mussa *m = new Mussa;
- m->load_mupa_file(mupa_path.toStdString());
- m->analyze(0, 0, Mussa::TransitiveNway, 0.0);
- // only switch mussas if we loaded without error
- delete mussaAnalysis;
- mussaAnalysis = m;
- updateScene();
- } catch (mussa_load_error e) {
- QString msg("Unable to load ");
- msg += mupa_path;
- msg += "\n";
- msg += e.what();
- QMessageBox::warning(this, "Load Parameter", msg);
- }
- assert (mussaAnalysis != 0);
-}
-
-void PathScene::loadSavedAnalysis()
-{
- QString caption("Load a previously run analysis");
- QString muway_dir = QFileDialog::getExistingDirectory(this,
- caption,
- QDir::currentPath());
- // user hit cancel?
- if (muway_dir.isNull())
- return;
- // try to safely load
- try {
- Mussa *m = new Mussa;
- m->load(muway_dir.toStdString());
- // only switch mussas if we loaded without error
- delete mussaAnalysis;
- mussaAnalysis = m;
- updateScene();
- } catch (mussa_load_error e) {
- QString msg("Unable to load ");
- msg += muway_dir;
- msg += "\n";
- msg += e.what();
- QMessageBox::warning(this, "Load Parameter", msg);
- }
- assert (mussaAnalysis != 0);
-}
-
-void PathScene::setSoftThreshold(int threshold)
-{
- if (mussaAnalysis->get_threshold() != threshold) {
- mussaAnalysis->set_soft_thres(threshold);
- mussaAnalysis->nway();
- update();
- }
+*/
}
////////////////////
// Rendering code
void PathScene::initializeGL()
{
- glEnable(GL_DEPTH_TEST);
- glClearColor(1.0, 1.0, 1.0, 0.0);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glShadeModel(GL_FLAT);
+ GlTracks::initializeGL();
}
void PathScene::resizeGL(int width, int height)
{
- viewport_width = width;
- viewport_height = height;
- assert (geometry().width() == width);
- assert (geometry().height() == height);
- glViewport(0, 0, (GLsizei)width, (GLsizei)height);
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- // I'm abusing this as Qt and OpenGL disagree about the direction of the
- // y axis
- glOrtho(curOrtho2d.left(), curOrtho2d.right(),
- curOrtho2d.top(), curOrtho2d.bottom(),
- -50.0, clipZ);
+ GlTracks::resizeGL(width, height);
}
void PathScene::paintGL()
{
- glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
-
- glPushMatrix();
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glOrtho(curOrtho2d.left(), curOrtho2d.right(),
- curOrtho2d.top(), curOrtho2d.bottom(),
- -50.0, clipZ);
- glMatrixMode(GL_MODELVIEW);
- mussaesque();
- glEnable(GL_BLEND);
- glDepthMask(GL_FALSE);
- if (selectedMode && !drawingBand) {
- glColor4f(0.6, 0.6, 0.6, 0.9);
- glRectf(previousBand.x(), previousBand.y(),
- previousBand.right(), previousBand.bottom());
- }
- glDepthMask(GL_TRUE);
- glDisable(GL_BLEND);
- glPopMatrix();
- glFlush();
-}
-
-void PathScene::updateScene()
-{
- // Delete old glsequences
- // FIXME: does this actually free the memory from the new'ed GlSequences?
- tracks.clear();
-
- // save a reference to our GlSequences
- GlSequence *gl_seq;
- float y = mussaAnalysis->sequences().size() * 100 ;
- float max_base_pairs = 0;
- typedef vector<Sequence>::const_iterator seqs_itor_t;
- for(seqs_itor_t seq_itor = mussaAnalysis->sequences().begin();
- seq_itor != mussaAnalysis->sequences().end();
- ++seq_itor)
- {
- y = y - 100;
- gl_seq = new GlSequence(*seq_itor, mussaAnalysis->colorMapper());
- gl_seq->setX(0);
- gl_seq->setY(y);
- if (gl_seq->length() > max_base_pairs ) max_base_pairs = gl_seq->length();
- tracks.push_back( *gl_seq );
- }
- maxOrtho2d.setWidth(max_base_pairs + 100.0);
- maxOrtho2d.setHeight((mussaAnalysis->sequences().size()) * 100 );
- curOrtho2d = maxOrtho2d;
- viewport_center = (curOrtho2d.right()-curOrtho2d.left())/2+curOrtho2d.left();
+ GlTracks::paintGL();
}
+/*
void PathScene::processSelection(GLuint hits, GLuint buffer[], GLuint bufsize)
{
const size_t pathz_count = mussaAnalysis->paths().refined_pathz.size();
resizeGL(geometry().width(), geometry().height());
}
-
-
-//////
-// openGl rendering code
-
-void PathScene::draw_tracks() const
-{
- glPushMatrix();
- glPushName(0);
- for (vector<GlSequence>::size_type i = 0; i != tracks.size(); ++i )
- {
- glLoadName(i);
- tracks[i].draw(curOrtho2d.left(), curOrtho2d.right());
- }
- glPopName();
- glPopMatrix();
-}
-
-void PathScene::draw_lines() const
-{
- GLfloat x;
- GLfloat y;
- GLuint pathid=0;
- GLint objid=0;
- bool reversed = false;
- bool prevReversed = false;
- const NwayPaths& nway = mussaAnalysis->paths();
-
- glPushName(pathid);
- glLineWidth(2);
- vector<GlSequence>::const_iterator track_itor;
-
- typedef list<ExtendedConservedPath> conserved_paths;
- typedef conserved_paths::const_iterator const_conserved_paths_itor;
- for(const_conserved_paths_itor path_itor = nway.refined_pathz.begin();
- path_itor != nway.refined_pathz.end();
- ++path_itor, ++objid)
- {
- track_itor = tracks.begin();
- // since we were drawing to the start of a window, and opengl lines
- // are centered around the two connecting points our lines were slightly
- // offset. the idea of window_offset is to adjust them to the
- // right for forward compliment or left for reverse compliment
- // FIXME: figure out how to unit test these computations
- GLfloat window_offset = (path_itor->window_size)/2.0;
-
- glBegin(GL_LINE_STRIP);
- for (vector<int>::const_iterator sp_itor = path_itor->begin();
- sp_itor != path_itor->end();
- ++sp_itor, ++track_itor)
- {
- x = *sp_itor;
- y = track_itor->y();
- // at some point when we modify the pathz data structure to keep
- // track of the score we can put grab the depth here.
- //
- // are we reverse complimented?
- if ( x>=0) {
- reversed = false;
- } else {
- reversed = true;
- x = -x; // make positive
- }
- if (!reversed)
- x += window_offset; // move right for forward compliment
- else
- x -= window_offset; // move left for reverse compliment
- // the following boolean implements logical xor
- if ( (reversed || prevReversed) && (!reversed || !prevReversed)) {
- // we have a different orientation
- if (not selectedMode or selectedPaths[objid] == true) {
- // if we have nothing selected, or we're the highlight, be bright
- glColor3f(0.0, 0.0, 1.0);
- } else {
- // else be dim
- glColor3f(0.7, 0.7, 1.0);
- }
- } else {
- // both current and previous path have the same orientation
- if (not selectedMode or selectedPaths[objid] == true) {
- glColor3f(1.0, 0.0, 0.0);
- } else {
- glColor3f(1.0, 0.7, 0.7);
- }
- }
- prevReversed = reversed;
- glVertex3f(x, y, -1.0);
- }
- glEnd();
- glLoadName(++pathid);
- }
- glPopName();
-}
-
-GLuint PathScene::make_line_list()
-{
- GLuint line_list = glGenLists(1);
- glNewList(line_list, GL_COMPILE);
-
- draw_lines();
-
- glEndList();
- return line_list;
-
-}
-
-void PathScene::mussaesque()
-{
- //static GLuint theLines = make_line_list();
-
- glInitNames();
- glPushName(MussaPaths);
- //glCallList(theLines);
- draw_lines();
- glLoadName(MussaTracks);
- draw_tracks();
- glPopName();
-}
-
+*/