++pathid;
}
+void GlSeqBrowser::setSelectedPaths(std::vector<int> paths)
+{
+ selected_paths.clear();
+ for(std::vector<int>::iterator itor = paths.begin();
+ itor != paths.end();
+ ++itor)
+ {
+ selected_paths.insert(*itor);
+ }
+}
+
const set<int>& GlSeqBrowser::selectedPaths() const
{
return selected_paths;
}
+void GlSeqBrowser::appendSelectedTrack(GLuint track, int start, int stop)
+{
+ selected_tracks.push_back(TrackRegion(track, start, stop));
+}
+
+list<TrackRegion> GlSeqBrowser::selectedTracks() const
+{
+ return selected_tracks;
+}
+
//! copy sequence from selected track using formating function
template<class Item>
void GlSeqBrowser::copySelectedTracks(std::list<Item>& result,
static string formatter(const Sequence& seq, int left, int right)
{
stringstream s;
- s << ">" << seq.get_header()
+ s << ">" << seq.get_fasta_header()
<< "|" << "subregion=" << left << "-" << right+1
<< std::endl
<< seq.subseq(left, right-left+1) << std::endl;
#include "alg/sequence.hpp"
#include "alg/glsequence.hpp"
#include "alg/sequence_location.hpp"
+#include "alg/track_region.hpp"
//! Manage rendering a collection of glSequences
class GlSeqBrowser
void clear_links();
//! define a path
void link(const std::vector<int>& path, const std::vector<bool>& isRC, int length);
+ //! set selected paths (it'd be nice if this could be a templated function)
+ void setSelectedPaths(std::vector<int> c);
//! returns the index of pathids based on order added by link
const std::set<int>& selectedPaths() const;
+
+ //! set selected tracks (it'd be nice if this could be a templated function)
+ void appendSelectedTrack(GLuint track_index, int left, int right);
+
+ //! return list of selected tracks
+ std::list<TrackRegion> selectedTracks() const;
+
//! copy sequence from selected track using formating function
template<class Item>
void copySelectedTracks(std::list<Item>& result,
typedef std::vector<pair_segment_map> path_segment_map_vector;
path_segment_map_vector path_segments;
- struct TrackRegion
- {
- GLuint track_id;
- int left;
- int right;
-
- TrackRegion():track_id(0), left(0), right(0) {};
- TrackRegion(const TrackRegion& o)
- : track_id(o.track_id), left(o.left), right(o.right) {}
- TrackRegion(GLuint id, int l, int r)
- : track_id(id), left(l), right(r) {}
- void set(GLuint id, int l, int r) { track_id = id; left=l; right=r; };
- };
-
private:
//! recalculate the viewable world
/*! depending on the size of our canvas, our zoom level and
//std::cout << "adding seq: " << name << " " << new_seq << std::endl;
Sequence s(new_seq);
- s.set_header(name);
+ s.set_fasta_header(name);
seq_list.push_back(s);
};
};
find_sequences(query_seqs.begin(), query_seqs.end());
}
-void Sequence::set_species(const std::string& name)
-{
- species = name;
-}
-
-std::string Sequence::get_species() const
-{
- return species;
-}
-
void Sequence::add_annotation(const annot& a)
{
annots.push_back(a);
count = size()-start;
}
Sequence new_seq(std::string::substr(start, count));
- new_seq.set_header(get_header());
+ new_seq.set_fasta_header(get_fasta_header());
//new_seq.set_species(get_species());
new_seq.motif_list = motif_list;
return rev_comp;
}
-void Sequence::set_header(std::string header_)
+void Sequence::set_fasta_header(std::string header_)
{
header = header_;
}
+void Sequence::set_species(const std::string& name)
+{
+ species = name;
+}
+
+std::string Sequence::get_species() const
+{
+ return species;
+}
+
+
std::string
-Sequence::get_header() const
+Sequence::get_fasta_header() const
{
return header;
}
-/*
-std::string
-Sequence::species()
+std::string
+Sequence::get_name() const
{
- return species;
+ if (header.size() > 0)
+ return header;
+ else if (species.size() > 0)
+ return species;
+ else
+ return "";
}
-*/
void
Sequence::clear()
std::list<Sequence>::iterator end)
{
while (start != end) {
- add_string_annotation(*start, start->get_header());
+ add_string_annotation(*start, start->get_fasta_header());
++start;
}
}
void add_annotation(const annot& a);
const std::list<annot>& annotations() const;
const std::list<motif>& motifs() const;
- void set_species(const std::string &);
- std::string get_species() const;
//! return a subsequence, copying over any appropriate annotation
Sequence subseq(int start=0, int count = std::string::npos) const;
//! clear the sequence and its annotations
void clear();
- void set_header(std::string header);
- std::string get_header() const;
+ //! set species name
+ void set_species(const std::string &);
+ //! get species name
+ std::string get_species() const;
+ //! set the fasta header
+ void set_fasta_header(std::string header);
+ //! get the fasta header
+ std::string get_fasta_header() const;
+ //! get name (will return the first non-empty, of fasta_header, species)
+ std::string get_name() const;
+
//! add a motif to our list of motifs
//! \throws motif_normalize_error if there's something wrong with a_motif
void add_motif(const Sequence& a_motif);
return *sequence;
}
+Sequence SequenceLocation::getSelectedSequence() const
+{
+ return sequence->subseq(left, count);
+}
+
void SequenceLocation::setLeft(int l)
{
left = l;
SequenceLocation(const SequenceLocation& );
SequenceLocation& operator=(const SequenceLocation&);
+ //! get the sequence we're selecting from
const Sequence& getSequence() const;
+ //! return the selected subsequence
+ Sequence getSelectedSequence() const;
void setLeft(int l);
int getLeft() const;
void setCount(int c);
BOOST_CHECK_EQUAL( gt.sequences()[1].x(), (gt.viewportCenter()-15)-path[1] );
BOOST_CHECK_EQUAL( gt.sequences()[2].x(), (gt.viewportCenter()-15)-path[2] );
}
+
+BOOST_AUTO_TEST_CASE( setSelectedPaths )
+{
+ string s0("AAGGCCTT");
+ string s1("TTGGCCAA");
+ string s2("GATTACAA");
+ Sequence seq0(s0);
+ Sequence seq1(s1);
+ Sequence seq2(s2);
+
+ GlSeqBrowser gt;
+ gt.push_sequence(seq0);
+ gt.push_sequence(seq1);
+ gt.push_sequence(seq2);
+
+ // make up some sample data
+ vector<bool> rc;
+ rc += false, false, false;
+ vector<int> path;
+ path += 1,1,1; gt.link(path, rc, 1);
+ path.clear(); path += 1,1,3; gt.link(path, rc, 1);
+ path.clear(); path += 2,3,3; gt.link(path, rc, 1);
+ path.clear(); path += 3,3,3; gt.link(path, rc, 1);
+
+ vector<int> selected;
+ selected += 1,4;
+ BOOST_CHECK_EQUAL( gt.selectedPaths().size(), 0 );
+ gt.setSelectedPaths(selected);
+ BOOST_CHECK_EQUAL( gt.selectedPaths().size(), selected.size() );
+ gt.clear_selection();
+ BOOST_CHECK_EQUAL( gt.selectedPaths().size(), 0);
+}
+
+BOOST_AUTO_TEST_CASE( setSelectedTracks )
+{
+ string s0("AAGGCCTT");
+ string s1("TTGGCCAA");
+ string s2("GATTACAA");
+ Sequence seq0(s0);
+ Sequence seq1(s1);
+ Sequence seq2(s2);
+
+ GlSeqBrowser gt;
+ gt.push_sequence(seq0);
+ gt.push_sequence(seq1);
+ gt.push_sequence(seq2);
+
+
+ BOOST_CHECK_EQUAL( gt.selectedTracks().size(), 0 );
+ gt.appendSelectedTrack(0, 0, seq0.size());
+ gt.appendSelectedTrack(2, 0, seq2.size());
+ BOOST_CHECK_EQUAL( gt.selectedTracks().size(), 2 );
+
+ list<Sequence> selected_sequence;
+ BOOST_CHECK_EQUAL(selected_sequence.size(), 0);
+ gt.copySelectedTracksAsSequences(selected_sequence);
+ BOOST_CHECK_EQUAL(selected_sequence.size(), 2);
+ BOOST_CHECK_EQUAL(selected_sequence.front(), seq0);
+ BOOST_CHECK_EQUAL(selected_sequence.back(), seq2);
+
+ gt.clear_selection();
+ BOOST_CHECK_EQUAL( gt.selectedPaths().size(), 0);
+
+ gt.appendSelectedTrack(0, 0, 2);
+ list<SequenceLocation> seq_locs;
+ gt.copySelectedTracksAsSeqLocation(seq_locs);
+ BOOST_CHECK_EQUAL(seq_locs.size(), 1);
+ BOOST_CHECK_EQUAL(seq_locs.front().getSequence(), seq0);
+ BOOST_CHECK_EQUAL(seq_locs.front().getLeft(), 0);
+ BOOST_CHECK_EQUAL(seq_locs.front().getRight(), 2);
+
+}
s.load_fasta(seq_path);
BOOST_CHECK_EQUAL(s.subseq(0, 5), "GGATC"); // first few chars of fasta file
BOOST_CHECK_EQUAL(s.subseq(2, 3), "ATC");
- BOOST_CHECK_EQUAL(s.get_header(), "gi|180579|gb|M21487.1|HUMCKMM1 Human "
+ BOOST_CHECK_EQUAL(s.get_fasta_header(), "gi|180579|gb|M21487.1|HUMCKMM1 Human "
"muscle creatine kinase gene (CKMM), "
"5' flank");
}
/* FIXME: enable this when i find a way of passing storing the motif name
// does our annotation travel?
Sequence motif_seq(m);
- motif_seq.set_header("hi");
+ motif_seq.set_fasta_header("hi");
s1.add_motif(motif_seq);
BOOST_CHECK_EQUAL(s1.motifs().size(), 2);
BOOST_CHECK_EQUAL( s, buf.str() );
}
+BOOST_AUTO_TEST_CASE( get_name )
+{
+ Sequence seq("AAGGCCTT");
+
+ BOOST_CHECK_EQUAL( seq.get_name(), "" );
+ seq.set_species("hooman"); // anyone remember tradewars?
+ BOOST_CHECK_EQUAL( seq.get_name(), "hooman");
+ seq.set_fasta_header("fasta human");
+ BOOST_CHECK_EQUAL( seq.get_name(), "fasta human");
+}
}
BOOST_CHECK_EQUAL(sl->getSequence(), "AAGGCCTT");
+ BOOST_CHECK_EQUAL(sl->getSelectedSequence(), "AA");
}
--- /dev/null
+#ifndef TRACK_REGION_HPP_
+#define TRACK_REGION_HPP_
+
+struct TrackRegion
+{
+ GLuint track_id;
+ int left;
+ int right;
+
+ TrackRegion():track_id(0), left(0), right(0) {};
+ TrackRegion(const TrackRegion& o)
+ : track_id(o.track_id), left(o.left), right(o.right) {}
+ TrackRegion(GLuint id, int l, int r)
+ : track_id(id), left(l), right(r) {}
+ void set(GLuint id, int l, int r) { track_id = id; left=l; right=r; };
+};
+#endif
.def("__str__", &seq_to_string)
.def("size", &Sequence::size)
.def("__len__", &Sequence::size)
- .add_property("header", &Sequence::get_header, &Sequence::set_header)
+ .add_property("header", &Sequence::get_fasta_header, &Sequence::set_fasta_header)
.add_property("species", &Sequence::get_species, &Sequence::set_species)
.def("rcseq", &Sequence::rev_comp, return_value_policy<return_by_value>())
;
mussa_setup_dialog/MussaSetupWidget.hpp
mussa_setup_dialog/SequenceSetupFrame.hpp
mussa_setup_dialog/SequenceSetupWidget.hpp
- mussa_setup_dialog/SetupInfo.hpp
seqbrowser/ScrollableSequenceBrowser.hpp
seqbrowser/SequenceBrowser.hpp
seqbrowser/SequenceBrowserSidebar.hpp
#include "mussa_exceptions.hpp"
#include <memory>
+#include <iterator>
#include <iostream>
#include <boost/filesystem/path.hpp>
void MussaWindow::createSubAnalysis()
{
+ list<SequenceLocation> result;
+ SequenceLocationModel& model = subanalysis_window.getModel();
+ browser.copySelectedTracksAsSeqLocation(result);
+ for(list<SequenceLocation>::iterator result_itor = result.begin();
+ result_itor != result.end();
+ ++result_itor)
+ {
+ model.push_back(*result_itor);
+ }
+
if (not subanalysis_window.isVisible()) {
subanalysis_window.show();
}
SequenceLocationModel::SequenceLocationModel(QObject *parent)
: QAbstractTableModel(parent)
{
- Sequence s("AGCT");
}
void SequenceLocationModel::assign(
return sequence_locations.begin();
}
+void SequenceLocationModel::clear()
+{
+ if (sequence_locations.size() != 0) {
+ beginRemoveRows(QModelIndex(), 0, sequence_locations.size()-1);
+ sequence_locations.pop_back();
+ endRemoveRows();
+ }
+}
+
SequenceLocationModel::iterator SequenceLocationModel::end()
{
return sequence_locations.end();
void SequenceLocationModel::pop_back()
{
- sequence_locations.pop_back();
+ int last_element = sequence_locations.size()-1;
+ if (last_element >= 0) {
+ beginRemoveRows(QModelIndex(), last_element, last_element);
+ sequence_locations.pop_back();
+ endRemoveRows();
+ }
}
void SequenceLocationModel::push_back(SequenceLocation& item)
{
+ int last_element = sequence_locations.size();
+ beginInsertRows(QModelIndex(), last_element, last_element);
sequence_locations.push_back(item);
+ endInsertRows();
}
SequenceLocationModel::size_type SequenceLocationModel::size() const
if (role == Qt::DisplayRole) {
if (index.column() == 0 ) {
const Sequence& seq = sequence_locations[index.row()].getSequence();
- std::string header(seq.get_header());
- if (header.size() == 0) {
- return QVariant(QString(tr("Sequence ")) +
- QString().setNum(index.row())
- );
+ std::string name(seq.get_name());
+ if (name.size() == 0) {
+ return QString(tr("Unnamed Sequence"));
} else {
- return QVariant(QString(header.c_str()));
+ return QVariant(QString(name.c_str()));
}
} else if (index.column() == 1) {
return QVariant(sequence_locations[index.row()].getLeft());
QVariant
SequenceLocationModel::headerData(
int section,
- Qt::Orientation orentation,
+ Qt::Orientation orientation,
int role
-)
+) const
{
- switch(section) {
- case 0:
- return QString("Sequence");
- break;
- case 1:
- return QString("Left");
- break;
- case 2:
- return QString("Right");
- break;
- default:
- return QVariant();
- break;
+ if (role != Qt::DisplayRole)
+ return QVariant();
+
+ if (orientation == Qt::Horizontal) {
+ switch(section) {
+ case 0:
+ return QString("Sequence");
+ break;
+ case 1:
+ return QString("Left");
+ break;
+ case 2:
+ return QString("Right");
+ break;
+ default:
+ return QVariant();
+ break;
+ }
}
+ return QVariant();
}
iterator begin();
//! return an iterator to the beginning of the model
const_iterator begin() const;
+ //! empty the model
+ void clear();
//! return an iterator to the end of the model
iterator end();
//! return an iterator to the end of the model
int columnCount(const QModelIndex& parent=QModelIndex()) const;
QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const;
- QVariant headerData(int section, Qt::Orientation orentation, int role=Qt::DisplayRole);
+ QVariant headerData(int section, Qt::Orientation orientation, int role=Qt::DisplayRole) const;
//bool setData(const QModelIndex& index, const QVariant &value,
// int role=Qt::EditRole);
#include "qui/SubanalysisWindow.hpp"
+#include "qui/MussaWindow.hpp"
+
+#include "mussa_exceptions.hpp"
+#include "alg/mussa.hpp"
#include <QVBoxLayout>
#include <QHBoxLayout>
+#include <QGridLayout>
SubanalysisWindow::SubanalysisWindow(QWidget *parent)
: QWidget(parent),
+ window(0),
+ threshold(0),
table(0),
ok(0),
cancel(0)
{
- //model.setStringList(string_list);
+ QGridLayout *parameterLayout = new QGridLayout;
- QHBoxLayout *buttonLayout = new QHBoxLayout();
- QVBoxLayout *verticalLayout = new QVBoxLayout();
+ QLabel *thresholdLabel = new QLabel(tr("threshold (bp)"));
+ parameterLayout->addWidget(thresholdLabel, 0, 0);
+ threshold = new QSpinBox(this);
+ threshold->setValue(8);
+ parameterLayout->addWidget(threshold, 1, 0);
+ QLabel *windowLabel = new QLabel(tr("window (bp)"));
+ parameterLayout->addWidget(windowLabel, 0, 1);
+ window = new QSpinBox(this);
+ window->setValue(10);
+ parameterLayout->addWidget(window, 1, 1);
ok = new QPushButton(tr("&OK"), this);
+ connect(ok, SIGNAL(clicked()), this, SLOT(run()));
cancel = new QPushButton(tr("Cancel"), this);
+ connect(cancel, SIGNAL(clicked()), this, SLOT(abort()));
table = new QTableView(this);
table->setModel(&model);
+ // layout buttons
+ QHBoxLayout *buttonLayout = new QHBoxLayout;
buttonLayout->addWidget(ok);
buttonLayout->addWidget(cancel);
+
+ // layout verticle space
+ QVBoxLayout *verticalLayout = new QVBoxLayout;
+ verticalLayout->addLayout(parameterLayout);
verticalLayout->addWidget(table);
verticalLayout->addLayout(buttonLayout);
setLayout(verticalLayout);
}
+
+SequenceLocationModel& SubanalysisWindow::getModel()
+{
+ return model;
+}
+
+void SubanalysisWindow::abort()
+{
+ model.clear();
+ hide();
+}
+
+void SubanalysisWindow::run()
+{
+ if (window == 0 or threshold == 0)
+ throw std::runtime_error("SubanalysisWindow misconstructed");
+
+ std::auto_ptr<Mussa> m(new Mussa);
+
+ for(SequenceLocationModel::iterator itor = model.begin();
+ itor != model.end();
+ ++itor)
+ {
+ m->append_sequence(itor->getSelectedSequence());
+ }
+
+ m->set_window(window->value());
+ m->set_threshold(threshold->value());
+ m->analyze();
+ MussaWindow *mw = new MussaWindow(m.get());
+ mw->show();
+ model.clear();
+ hide();
+}
+
#include <QTableView>
#include <QPushButton>
+#include <QSpinBox>
#include <QStringList>
#include <QWidget>
public:
SubanalysisWindow(QWidget *parent = 0);
+ //! return a modifiable reference to our SequenceLocationModel
+ SequenceLocationModel& getModel();
+
+public slots:
+ //! clear our model and close the window
+ void abort();
+
+ //! create a subanalysis and run it
+ void run();
+
private:
+ QSpinBox *window;
+ QSpinBox *threshold;
QTableView *table;
QPushButton *ok;
QPushButton *cancel;
{
if ((*md_i)->motif().size() > 0 && (*md_i)->enabled()) {
Sequence new_motif((*md_i)->motif());
- new_motif.set_header((*md_i)->name());
+ new_motif.set_fasta_header((*md_i)->name());
motifs.push_back((*md_i)->motif());
colors.push_back((*md_i)->color());
}
scrollable_browser.browser().copySelectedSequenceAsFasta();
}
+void SequenceBrowserWidget::copySelectedTracksAsSeqLocation(
+ std::list<SequenceLocation>& locations
+)
+{
+ scrollable_browser.browser().copySelectedTracksAsSeqLocation(locations);
+}
+
void SequenceBrowserWidget::setSequences(
const std::vector< boost::shared_ptr<Sequence> >& sequences,
boost::shared_ptr<AnnotationColors> cm)
//! return our copy actioy (reference stored internally)
QAction &getCopySelectedSequenceAsFastaAction();
+ //! copy selected track regions into a list of SequenceLocations
+ void copySelectedTracksAsSeqLocation(std::list<SequenceLocation>& );
+
//! return current zoom size
double zoom();
ENDMACRO(MAKE_UNITTEST)
MAKE_UNITTEST(TestSequenceLocationModel)
+MAKE_UNITTEST(TestSequenceBrowser)
+MAKE_UNITTEST(TestColorSharing)
--- /dev/null
+#include <QtGui>
+#include <QtTest/QtTest>
+
+#include "alg/mussa.hpp"
+#include "alg/color.hpp"
+#include "qui/MussaWindow.hpp"
+
+//! do our colors get shared correctly between different windows?
+class TestColorSharing : public QObject
+{
+ Q_OBJECT
+
+private slots:
+
+ void simple2sequence() {
+ Color green(0.0, 1.0, 0.0);
+ Mussa m;
+ m.append_sequence("AAGGCCTT");
+ m.append_sequence("GGTTCCAA");
+ m.set_window(2);
+ m.set_threshold(2);
+ m.analyze();
+
+ //MussaWindow mw(&m);
+ m.add_motif("GG", green);
+ }
+};
+
+QTEST_MAIN(TestColorSharing)
+#include "moc_TestColorSharing.cxx"
--- /dev/null
+#include <QtGui>
+#include <QtTest/QtTest>
+
+#include "alg/sequence.hpp"
+#include "qui/seqbrowser/SequenceBrowser.hpp"
+
+#include <iostream>
+#include <string>
+#include <vector>
+
+#include <boost/assign.hpp>
+using namespace boost::assign;
+
+
+class TestSequenceBrowser : public QObject
+{
+ Q_OBJECT
+
+private slots:
+
+ void testSimplePushSequence() {
+ Sequence seq1("AAGGCCTT");
+ Sequence seq2("GGCCTTAA");
+
+ SequenceBrowser browser;
+ QVERIFY(browser.sequences().size() == 0);
+ browser.push_sequence(seq1);
+ browser.push_sequence(seq2);
+ QVERIFY(browser.sequences().size() == 2);
+ browser.clear();
+ QVERIFY(browser.sequences().size() == 0);
+ }
+
+ void testSelect() {
+ Sequence seq1("AAGGCCTT");
+ Sequence seq2("GGCCTTAA");
+
+ SequenceBrowser browser;
+ browser.push_sequence(seq1);
+ browser.push_sequence(seq2);
+ std::vector<int> path; path += 1,1;
+ std::vector<bool> rc; rc += false, false;
+ browser.link(path, rc, 2);
+
+ }
+};
+
+QTEST_MAIN(TestSequenceBrowser)
+#include "moc_TestSequenceBrowser.cxx"