we can load parameter files
authorDiane Trout <diane@caltech.edu>
Fri, 3 Mar 2006 07:54:47 +0000 (07:54 +0000)
committerDiane Trout <diane@caltech.edu>
Fri, 3 Mar 2006 07:54:47 +0000 (07:54 +0000)
Mussagl now as several ways to load an analysis.
There are now two command-line arguments, run-analysis and view-analysis
which will load a parameter file and an analysis directory respectively.

The menu items in mussagl are also connected to slots in PathScene to
handle loading.

When something is loaded PathScene::updateAnalysis will (if the
analysis actually has some contents) run the analysis.

However there's some bug where the loading the previously saved analysis
is choaking on some assertion.

12 files changed:
alg/mussa_class.cxx
alg/mussa_class.hh
alg/nway_paths.cxx
alg/parse_options.cxx [new file with mode: 0644]
alg/parse_options.h [new file with mode: 0644]
alg/test/test_mussa.cxx
mussagl.cxx
mussagl.pro
qui/PathScene.cxx
qui/PathScene.h
qui/PathWindow.cxx
qui/PathWindow.h

index 266067a8c22cf0a06b672eed32380f6c93bceeb3..bd86a2f6d7ef8e5c1c5da7595c12e20fb2c9176d 100644 (file)
@@ -61,7 +61,12 @@ string Mussa::get_name()
 int 
 Mussa::size() const
 {
-  return the_seqs.size();
+  if (the_seqs.size() > 0)
+    return the_seqs.size();
+  else if (seq_files.size() > 0)
+    return seq_files.size();
+  else
+    return 0;
 }
 
 void
@@ -170,7 +175,7 @@ Mussa::load_mupa_file(string para_file_path)
   bool seq_params, did_seq;
   string err_msg;
   bool parsing_path;
-  int new_index, dir_index;
+  string::size_type new_index, dir_index;
 
 
   // initialize values
@@ -187,15 +192,13 @@ Mussa::load_mupa_file(string para_file_path)
     while (parsing_path)
     {
       new_index = (para_file_path.substr(dir_index)).find("/");
-      //cout << "mu class: "<< new_index << endl;
-      if (new_index > 0)
-       dir_index += new_index + 1;
+      if (new_index != string::npos)
+        dir_index += new_index + 1;
       else
-       parsing_path = false;
+        parsing_path = false;
     }
 
     file_path_base = para_file_path.substr(0,dir_index);
-    cout << "mu class: mupa base path = " << file_path_base << endl;
 
     // setup loop by getting file's first line
     getline(para_file,file_data_line);
@@ -221,6 +224,7 @@ Mussa::load_mupa_file(string para_file_path)
       else if (param == "SEQUENCE")
       {
         seq_files.push_back(file_path_base + value);
+        cout << "seq_file_name " << seq_files.back() << endl;
         fasta_index = 1;
         annot_file = "";
         sub_seq_start = 0;
@@ -550,7 +554,8 @@ Mussa::save_muway(string save_path)
 string
 Mussa::load(string ana_file)
 {
-  int i, i2, new_index, dir_index;
+  int i, i2;
+  string::size_type start_index, end_index;
   string file_path_base, a_file_path, ana_path;
   bool parsing_path;
   Sequence tmp_seq;
@@ -559,25 +564,28 @@ Mussa::load(string ana_file)
   vector<FLPs> empty_FLP_vector;
   FLPs dummy_comp;
 
+  cout << "ana_file name " << ana_file << endl;
   ana_path = ana_file;
   parsing_path = true;
-  dir_index = 0;
-  while (parsing_path)
-  {
-    new_index = (ana_path.substr(dir_index)).find("/");
-    //cout << "mu class: "<< new_index << endl;
-    if (new_index > 0)
-      dir_index += new_index + 1;
-    else
-      parsing_path = false;
+  end_index = ana_path.size()-1;
+  if (ana_path[end_index] == '/') { 
+    cout << "found trailing /" << endl;
+    --end_index;
   }
-
-  analysis_name = ana_path.substr(dir_index);
-  cout << "mu class: analysis_name = " << analysis_name << endl;
-  file_path_base = ana_path + "/" + ana_path.substr(dir_index);
+  start_index = ana_path.rfind('/', end_index);
+  if (start_index == string::npos) {
+    // no / to be found
+    start_index = 0;
+  } else {
+    // skip the / we found
+    ++start_index;
+  }
+  analysis_name = ana_path.substr(start_index, end_index-start_index+1);
+  cout << " ana_name " << analysis_name << endl;
+  file_path_base =  ana_path.substr(0, start_index) + analysis_name +"/" + analysis_name;
   a_file_path = file_path_base + ".muway";
+  cout << " loading museq: " << a_file_path << endl;
   err_msg = the_paths.load(a_file_path);
-  cout << "there is no safe distance\n";
 
   if (err_msg == "")
   {
@@ -591,7 +599,7 @@ Mussa::load(string ana_file)
     for (i = 1; i <= seq_num; i++)
     {
       tmp_seq.clear();
-      cout << "mussa_class: loading museq frag...\n";
+      cout << "mussa_class: loading museq frag... " << a_file_path << endl;
       tmp_seq.load_museq(a_file_path, i);
       the_seqs.push_back(tmp_seq);
     }
index 685f441709b320d43da5e305b43703b722d7237a..895018e6133ad9eabd328c40e127045dce515580 100644 (file)
@@ -49,6 +49,10 @@ class Mussa
     std::string get_name();
 
     //! return number of sequences in this analyzis
+    /*! this returns either the_seqs.size() or seq_files.size()
+     *  depending on which has data loaded in
+     *  (silly delayed loading of sequence data)
+     */
     int size() const;
     //! set number of bases for this window size
     void set_window(int a_window);
index bd6befd230fc401bfc93bedef8135baacd9e0b58..f5a0e84b2dc9fb656d1fca74345042a2233bb85f 100644 (file)
@@ -231,7 +231,6 @@ NwayPaths::load(string load_file_path)
     getline(load_file,file_data_line);
     while ( (!load_file.eof()) && (file_data_line != "</Mussa>") )
     {
-      cout << "fdl: " << file_data_line << endl;
       if (file_data_line != "")
       {
         loaded_path.clear();
diff --git a/alg/parse_options.cxx b/alg/parse_options.cxx
new file mode 100644 (file)
index 0000000..b2b731b
--- /dev/null
@@ -0,0 +1,44 @@
+#include <boost/program_options.hpp>
+namespace po = boost::program_options;
+
+#include <string>
+#include <iostream>
+
+#include "alg/mussa_class.hh"
+#include "alg/parse_options.h"
+
+Mussa *initialize_mussa(int argc, char **argv)
+{
+  po::options_description options("Mussa options");
+  po::positional_options_description pos_options;
+  pos_options.add("run-analysis", -1);
+
+  options.add_options()
+    ("help", "help message")
+    ("run-analysis,p", po::value<std::string>(), 
+     "run an analysis defined by the mussa parameter file")
+    ("view-analysis", po::value<std::string>(),
+     "load a previously run analysis")
+  ;
+
+  po::variables_map vm;
+  po::store(po::command_line_parser(argc, argv).options(options).positional(pos_options).run(), vm);
+  po::notify(vm);
+
+  if (vm.count("help")) {
+    std::cout << options << std::endl;
+    return 0;
+  }
+
+  Mussa *m = new Mussa();
+  // currently we can only have one analysis loaded, so 
+  // running trumps viewing.
+  if (vm.count("run-analysis")) {
+    m->load_mupa_file( vm["run-analysis"].as< std::string >() );
+  }
+  else if (vm.count("view-analysis")) {
+    m->load( vm["view-analysis"].as< std::string >() );
+  }
+  return m;
+}
+
diff --git a/alg/parse_options.h b/alg/parse_options.h
new file mode 100644 (file)
index 0000000..1dd3291
--- /dev/null
@@ -0,0 +1,9 @@
+#ifndef _PARSE_OPTIONS_H_
+#define _PARSE_OPTIONS_H_
+
+class Mussa;
+
+//! initialize a mussa analysis from command line arguments
+Mussa *initialize_mussa(int argc, char** argv);
+#endif
+
index 08d3d85b5a0ba327b9fd4f1aeff88cc4357111ce..a55b8b53624edc69351f67186f249504cfe8f82d 100644 (file)
@@ -75,4 +75,21 @@ BOOST_AUTO_TEST_CASE( mussa_load_mupa )
 
   BOOST_CHECK_EQUAL( m2.get_name(), saved_analysis_path );
   BOOST_CHECK_EQUAL( m1.size(), m2.size() );
+
+}
+
+BOOST_AUTO_TEST_CASE( mussa_load_full_path )
+{
+  Mussa m1;
+  chdir( "examples" );
+  const int bufsize = 1024;
+  char path_buf[bufsize];
+  getcwd(path_buf, bufsize);
+  std::string path(path_buf);
+  chdir( ".." );
+  path += "/mck3test.mupa";
+  m1.load_mupa_file( path );
+  m1.analyze(0, 0);
+
+  BOOST_CHECK( m1.size() > 0);
 }
index ddb4df50f439d87088046181ff73bff6bfa29bdf..99cd927963017dfb1e03763efbcd453db7324b66 100644 (file)
@@ -1,12 +1,18 @@
 #include <QApplication>
 
 #include "qui/PathWindow.h"
+#include "alg/parse_options.h"
 
 int main(int argc, char **argv)
 {
   QApplication app(argc, argv);
+  Mussa *analysis = initialize_mussa(argc, argv);
 
-  PathWindow win;
+  if (analysis == 0) {
+    return 1;
+  }
+
+  PathWindow win(analysis);
   win.show();
   app.exec();
 }
index 04c6cfd80ead4b488c9b1eda182104c198f5562c..52bee654ab3ff888fb411ddd5db4a7007bfc0e84 100644 (file)
@@ -22,6 +22,7 @@ HEADERS += mussa_exceptions.hh \
            alg/flp.hh \
            alg/mussa_class.hh \
            alg/nway_paths.hh \
+           alg/parse_options.h \
            alg/sequence.hh
 SOURCES += mussagl.cxx \
            qui/GlSequence.cxx \
@@ -37,6 +38,7 @@ SOURCES += mussagl.cxx \
            alg/nway_entropy.cxx \
            alg/nway_other.cxx \
            alg/nway_paths.cxx \
+           alg/parse_options.cxx \
 #           alg/nway_refine.cxx \
            alg/sequence.cxx 
 #           test/test_flp.cxx \
@@ -45,5 +47,5 @@ SOURCES += mussagl.cxx \
 #           test/test_nway.cxx \
 #           test/test_sequence.cxx 
 
-LIBS += -lm
+LIBS += -lm -lboost_program_options
 QT += opengl
index f4579a327d2e7753e66f72c0b08fc1b74837839f..3b077e6670783144ba89eeb82af92045605d61a3 100644 (file)
@@ -1,8 +1,11 @@
 #include "PathScene.h"
 
+#include <QDir>
+#include <QFileDialog>
 #include <QMouseEvent>
 #include <QRubberBand>
 #include <QRect>
+#include <QString>
 #include <iostream>
 
 #include <GL/gl.h>
 
 using namespace std;
 
-PathScene::PathScene(int frags, int len, QWidget *parent) : 
+PathScene::PathScene(Mussa* analysis, QWidget *parent) : 
   QGLWidget(parent),
   X(0),
   clipZ(30.0),
   zoom(0),
   maxOrtho2d(-50.0, -50, 3000000.0, 300.0),
   curOrtho2d(maxOrtho2d),
-  fragsize(frags),
-  length(len),
   rubberBand(0),
   debugBand(true),
   drawingBand(false)
 { 
-  // Hack in loading an analysis 
-  mussaAnalysis.load_mupa_file( "examples/mck3test.mupa" );
-  mussaAnalysis.analyze(0, 0, Mussa::TransitiveNway, 0.0);
-  //mussaAnalysis.load("mck3test_w30_t20");
-  updateAnalysis();
+  if (analysis == 0)
+  {
+    mussaAnalysis = new Mussa;
+  }
+  else
+  {
+    mussaAnalysis = analysis;
+    updateAnalysis();
+  }
 }
 
 QSize PathScene::sizeHint() const
@@ -93,15 +98,39 @@ void PathScene::setClipPlane(int newZ)
   }
 }
 
+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);
+  mussaAnalysis->load_mupa_file(mupa_path.toStdString());
+  updateAnalysis();
+}
+
+void PathScene::loadSavedAnalysis()
+{
+  QString caption("Load a previously run analysis");
+  QString muway_path = QFileDialog::getExistingDirectory(this,
+                                                         caption, 
+                                                         QDir::currentPath());
+  mussaAnalysis->load(muway_path.toStdString());
+  updateAnalysis();
+}
+
 void PathScene::setSoftThreshold(int threshold)
 {
-  if (mussaAnalysis.get_threshold() != threshold) {
-    mussaAnalysis.set_soft_thres(threshold);
-    mussaAnalysis.nway();
+  if (mussaAnalysis->get_threshold() != threshold) {
+    mussaAnalysis->set_soft_thres(threshold);
+    mussaAnalysis->nway();
     update();
   }
 }
 
+////////////////////
+// Rendering code
 void PathScene::initializeGL()
 {
   glEnable(GL_DEPTH_TEST);
@@ -149,27 +178,37 @@ void PathScene::paintGL()
 
 void PathScene::updateAnalysis()
 {
-  GlSequence *gl_seq;
-  float y = mussaAnalysis.sequences().size() * 100 ;
-  float max_base_pairs = 0;
   // Delete old glsequences
   // FIXME: does this actually free the memory from the new'ed GlSequences?
   tracks.clear();
-  // save a reference to our GlSequences
-  for(vector<Sequence>::const_iterator seq_itor = mussaAnalysis.sequences().begin();
-      seq_itor != mussaAnalysis.sequences().end();
-      ++seq_itor)
+
+  // Run analysis
+  cout << "updateA:" << mussaAnalysis->size() //<< mussaAnalysis->paths().size()
+       << endl;
+  if (mussaAnalysis->size() >= 2) 
   {
-    y = y - 100;
-    gl_seq = new GlSequence(*seq_itor);
-    gl_seq->setX(0);
-    gl_seq->setY(y);
-    if (gl_seq->width() > max_base_pairs ) max_base_pairs = gl_seq->width();
-    tracks.push_back( *gl_seq );
+    mussaAnalysis->analyze(0, 0, Mussa::TransitiveNway, 0.0);
+
+    // 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);
+      gl_seq->setX(0);
+      gl_seq->setY(y);
+      if (gl_seq->width() > max_base_pairs ) max_base_pairs = gl_seq->width();
+      tracks.push_back( *gl_seq );
+    }
+    maxOrtho2d.setWidth(max_base_pairs + 100.0);
+    maxOrtho2d.setHeight((mussaAnalysis->sequences().size()) * 100 );
+    curOrtho2d = maxOrtho2d;
   }
-  maxOrtho2d.setWidth(max_base_pairs + 100.0);
-  maxOrtho2d.setHeight((mussaAnalysis.sequences().size()) * 100 );
-  curOrtho2d = maxOrtho2d;
 }
 
 static void processHits(GLint hits, GLuint buffer[])
@@ -289,7 +328,7 @@ void PathScene::draw_lines() const
   GLfloat y;
   bool reversed = false;
   bool prevReversed = false;
-  const NwayPaths& nway = mussaAnalysis.paths();
+  const NwayPaths& nway = mussaAnalysis->paths();
 
   glLineWidth(0.5);
   vector<GlSequence>::const_iterator track_itor;
index 98cc7a35ebefa182f707ae220370f2c7a391897b..7347cef178a30bd9cb18de00fdc12466011c5b37 100644 (file)
@@ -19,17 +19,21 @@ class PathScene: public QGLWidget
   Q_OBJECT
 
 public: 
-  PathScene(int fragsize, int length, QWidget *parent=0);
+  PathScene(Mussa *analysis=0,  QWidget *parent=0);
 
   QSize sizeHint() const;
 
-  Mussa mussaAnalysis;
+  Mussa* mussaAnalysis;
   std::vector<GlSequence> tracks;
 
 public slots:
   void setX(int x);
   void setClipPlane(int z);
   void setZoom(int);
+  //! load a mussa parameter file (which specifies an analysis to run)
+  void loadMupa( );
+  //! load a previously run analysis
+  void loadSavedAnalysis();
   //! set the soft threshold used by the Nway_Path algorithm
   void setSoftThreshold(int thres);
   //! called when we've changed the analysis
@@ -45,8 +49,6 @@ protected:
   int zoom;
   QRectF maxOrtho2d;
   QRectF curOrtho2d;
-  int fragsize;
-  int length;
 
   void initializeGL();
   void resizeGL(int width, int height);
index 4ae4d5b8b1be91afefb5b930b5415aaf1ebecc1c..b6fc07a5e3a37e72a198fdc8f56396fa56336c3d 100644 (file)
 
 #include <iostream>
 
-PathWindow::PathWindow(QWidget *) :
+PathWindow::PathWindow(Mussa *analysis, QWidget *) :
   closeAction(0) // initialize one of the pointers to null as a saftey flag
 {
+  scene = new PathScene(analysis, this);
+
   setupActions();
   setupMainMenu();
 
-  scene = new PathScene(10000, 10, this);
   //This next setWhatsThis function prevents
   // a segfault when using WhatsThis feature with 
   // opengl widget.
@@ -89,11 +90,11 @@ void PathWindow::setupActions()
   
   loadMupaAction = new QAction(tr("Load Mussa Parameters"), this);
   connect(loadMupaAction, SIGNAL(triggered()), 
-          this, SLOT(loadMupa()));
+          scene, SLOT(loadMupa()));
 
   loadSavedAnalysisAction = new QAction(tr("Load &Analysis"), this);
   connect(loadSavedAnalysisAction, SIGNAL(triggered()), 
-          this, SLOT(loadSavedAnalysis()));
+          scene, SLOT(loadSavedAnalysis()));
   loadSavedAnalysisAction->setIcon(QIcon("icons/fileopen.png"));
 
   saveMotifListAction = new QAction(tr("Save Motifs"), this);
@@ -177,22 +178,6 @@ void PathWindow::loadMotifList()
   NotImplementedBox();
 }
 
-void PathWindow::loadMupa()
-{
-  QString caption("Load a mussa parameter file");
-  QString filter("Mussa Parameters (*.mupa)");
-  QString mupa_path = QFileDialog::getOpenFileName(this,
-                                                   caption, 
-                                                   QDir::currentPath(),
-                                                   filter);
-  scene->mussaAnalysis.load_mupa_file(mupa_path.toStdString());
-}
-
-void PathWindow::loadSavedAnalysis()
-{
-  NotImplementedBox();
-}
-
 void PathWindow::saveMotifList()
 {
   NotImplementedBox();
index 8f1c7da26be4bc2163c11a4146352872775e3042..ce63d18f65e32af5d5d7154ba5104743f18baf09 100644 (file)
@@ -6,13 +6,14 @@
 class QAction;
 class PathScene;
 class ImageSaveDialog;
+class Mussa;
 
 class PathWindow : public QMainWindow
 {
   Q_OBJECT
 
 public: 
-  PathWindow(QWidget *parent=0);
+  PathWindow(Mussa* analysis=0, QWidget *parent=0);
 
 public slots:
   //! display an about box, contemplating the politics of the author list
@@ -24,10 +25,6 @@ public slots:
   void createNewAnalysis();
   //! launch a sub analysis
   void createSubAnalysis();
-  //! load a mussa parameter file (which specifies an analysis to run)
-  void loadMupa( );
-  //! load a previously run analysis
-  void loadSavedAnalysis();
   //\@}
 
   //! \defgroup MotifHandling Handling of motif lists